Обработка аварийных выходов из программы Java - PullRequest
3 голосов
/ 26 февраля 2009

Предположим, у меня есть приложение Java, которое открывает соединение с базой данных. Обычно я добавляю connection.close () в блок finally, но этот блок не будет выполняться в случае операции уничтожения или любого другого ненормального завершения, не так ли? Существуют ли какие-либо другие меры предосторожности, которые я, как программист, могу предпринять, чтобы правильно закрыть соединение до выхода из приложения?

Ответы [ 6 ]

3 голосов
/ 26 февраля 2009

Если что-то внешнее убивает вашу программу, вы ничего не можете с этим поделать. Очевидно, они хотели остановить это, так как вы можете предотвратить их?

Я собирался предложить крюк отключения , но состояние Javadocs:

В редких случаях виртуальная машина может прервать , то есть прекратить работу без выключения полностью. Это происходит, когда виртуальная машина завершается извне, например, с помощью сигнала SIGKILL в Unix или TerminateProcess call в Microsoft Windows. Виртуальная машина также может прервать работу, если собственный метод не работает, например, из-за повреждения внутренних структур данных или попытки доступа к несуществующей памяти. Если виртуальная машина прерывает работу, то нельзя гарантировать, будут ли запущены какие-либо перехватчики завершения работы.

(акцент мой)

3 голосов
/ 26 февраля 2009

Вам следует взглянуть на метод Runtime.addShutdownHook () для Java (http://java.sun.com/javase/6/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread)).). Он позволяет вам добавить ловушку, которая будет вызываться при завершении виртуальной машины. Вы можете использовать ее для вызова процедуры очистки.

Это было бы для сигнала TERM. Сигнал KILL уничтожит процесс и не позволит ему выполнить какую-либо очистку (поскольку сигнал KILL не может быть перехвачен или проигнорирован принимающим процессом).

2 голосов
/ 26 февраля 2009
  1. Вам не нужно вызывать connection.close () при завершении работы приложения, поскольку операционная система автоматически закрывает все открытые файлы.
  2. Кроме того, метод finalize () соединения должен быть запущен перед автоматическим завершением работы приложения (если завершение работы нормальное, не прервано), и это должно закрыть соединение.
  3. В любом случае вы можете зарегистрировать shutdown-hooks , чтобы выполнить любую необходимую вам очистку (опять-таки, будет выполняться в обычных случаях отключения, а не ABORT).
2 голосов
/ 26 февраля 2009

Уничтожение программы в конечном итоге приведет к задержке потока TCP из вашей программы на ваш [Oracle|SQL Server|MySQL|PostgreSQL] сервер.

Сервер увидит его и откатит все ожидающие транзакции.

1 голос
/ 26 февраля 2009

Некоторый уровень ненормального завершения неизбежен. Как бы вы уловили событие, когда кабель питания был отключен от сервера?

1 голос
/ 26 февраля 2009

Когда вас действительно убивают (kill -9 в UNIX), вы ничего не можете сделать против этого.

A finally -блок - это максимум, что вы можете сделать, см. SO: В Java гарантированно вызывается блок «finally» (в основном методе)? для деталей.

...