データベース接続を開く Java アプリケーションがあるとします。通常であれば、finally ブロックに connection.close() を追加しますが、このブロックは kill 操作やその他の異常終了の場合には実行されませんよね? アプリケーションが終了する前に接続を適切に閉じるために、プログラマーとしてできるその他の予防策はありますか?
6 に答える
Java の Runtime.addShutdownHook() メソッドを確認する必要があります ( http://java.sun.com/javase/6/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread) )。仮想マシンの終了時に呼び出されるフックを追加できます。これを使用して、クリーンアップ ルーチンを呼び出すことができます。
ただし、これは TERM シグナルの場合です。KILL シグナルはプロセスを強制終了し、クリーンアップを実行できません (受信プロセスは KILL シグナルをキャッチまたは無視できないため)。
外部の何かによってプログラムが強制終了された場合、それに対してできることは何もありません。明らかに彼らはそれを止めたかったのですが、どうすれば彼らを防ぐことができますか?
シャットダウン フックを提案するつもりでしたが、Javadocs の状態:
まれに、仮想マシンが異常終了する、つまり正常にシャットダウンせずに実行を停止することがあります。これは、仮想マシンが外部で終了した場合に発生します。たとえば、
SIGKILL
Unix やTerminateProcess call
Microsoft Windows のシグナルで終了します。たとえば、内部データ構造が破損したり、存在しないメモリにアクセスしようとしたりして、ネイティブ メソッドが失敗した場合にも、仮想マシンは中止される可能性があります。仮想マシンが異常終了した場合、シャットダウン フックが実行されるかどうかは保証されません。
(私のものを強調)
プログラムを強制終了すると、最終的にTCP
プログラムから[Oracle|SQL Server|MySQL|PostgreSQL]
サーバーへのストリームがタイムアウトになります。
サーバーはそれを確認し、保留中のトランザクションをロールバックします。
- 開いているすべてのファイルはオペレーティング システムによって自動的に閉じられるため、アプリケーションのシャットダウン時に connection.close() を呼び出す必要はありません。
- また、アプリケーションが自動的にシャットダウンする前に Connection の finalize() メソッドを実行する必要があり (シャットダウンが正常であり、ABORT されていない場合)、接続を閉じる必要があります。
- いずれにせよ、shutdown-hooksを登録して、必要なクリーンアップを行うことができます (ここでも、ABORT ではなく、通常のシャットダウンの場合に実行されます)。
本当に殺されたら ( kill -9
UNIX で)、それに対しては何もできません。
-blockfinally
は、できることのほとんどです。SO: Java では、「最終的に」ブロックが (メイン メソッドで) 呼び出されることが保証されていますか? を参照してください。詳細については。