Когда запускаемая JVM (на самом деле написанная на Scala, но я склонен полагать, что решение будет примерно таким же для Groovy, Clojure или чистой Java), моя консольная программа завершается пользователем, нажимающим Ctrl< /kbd>+C (или последовательностью завершения работы системы, я не знаю, есть ли разница для программы), как мне убедиться, что внешние ресурсы, которые изменяет приложение (базы данных , файлы, абстрагированные ресурсы веб-сервиса) остаются в предсказуемом, логически неповрежденном состоянии?
Как бороться с ^C в консольных приложениях JVM?
Ответы (3)
Взгляните на Время выполнения.addShutdownHook.
Обычно вы используете его так:
Runtime.addShutdownHook(new Thread() {
public void run() {
// do your clean up here.
}
});
Вы можете попытаться реализовать крючок выключения, как указывали другие, НО:
В редких случаях виртуальная машина может прервать работу, то есть перестать работать без корректного завершения работы. Это происходит, когда виртуальная машина завершается извне, например сигналом SIGKILL в Unix или вызовом TerminateProcess в Microsoft Windows. Виртуальная машина также может прервать работу, если собственный метод пойдет не так, например, из-за повреждения внутренних структур данных или попытки доступа к несуществующей памяти. Если виртуальная машина аварийно завершает работу, то нельзя гарантировать, будут ли запущены какие-либо перехватчики выключения.
Я думаю, вам придется ввести транзакционный контекст в ваше приложение, я полагаю. Для баз данных это довольно просто, для файловой системы вы можете изучить Транзакции Apache Commons
Вы можете перехватить этот сигнал и закрыть ресурсы. Большинство сервисов не нужно корректно закрывать, однако файлы, в которые вы пишете, обычно это делают.
Возможно, вам нужно просто добавить хук выключения. Но я бы проверил это для вашей ситуации.