假设我有一个打开数据库连接的Java应用程序。通常我会在finally块中添加一个connection.close(),但是在kill操作或任何其他异常终止的情况下不会执行此块,是吗?作为程序员,我是否可以在应用程序退出之前正确关闭连接?
答案 0 :(得分:3)
您应该查看Java的Runtime.addShutdownHook()方法(http://java.sun.com/javase/6/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread))。它允许您添加将在虚拟机终止时调用的挂钩。您可以使用它来调用清理例程。
那将是一个TERM信号。 KILL信号将终止进程并且不允许它进行任何清理(因为接收进程无法捕获或忽略KILL信号)。
答案 1 :(得分:3)
如果外部事件导致您的程序被杀,那么您无能为力。显然他们想阻止它,所以你怎么能阻止它们呢?
我打算建议shutdown hook,但是Javadocs状态:
在极少数情况下,虚拟机可能中止,即停止运行而不会干净地关闭。当虚拟机在外部终止时会发生这种情况,例如Unix上的
SIGKILL
信号或Microsoft Windows上的TerminateProcess call
。如果本机方法因例如破坏内部数据结构或尝试访问不存在的内存而出错,则虚拟机也可能中止。 如果虚拟机中止,则无法保证是否会运行任何关闭挂钩。
(强调我的)
答案 2 :(得分:2)
杀死程序最终会导致TCP
流从您的程序暂停到[Oracle|SQL Server|MySQL|PostgreSQL]
服务器。
服务器将看到它并回滚任何待处理的事务。
答案 3 :(得分:2)
答案 4 :(得分:1)
当你真的被杀死(在UNIX上kill -9
)时,你无法对此做任何事情。
finally
- 阻止是您可以执行的最多操作,有关详细信息,请参阅SO: In Java, is the “finally” block guaranteed to be called (in the main method)?。
答案 5 :(得分:1)
某种程度的异常终止是不可避免的。您如何捕获服务器上拉动电源线的事件?