在 J2EE 应用程序中优雅地处理 DB 节点重启

Gracefully handling DB Node reboot in J2EE application

在我的组织中,Oracle 数据库是一个 2 节点 RAC 数据库。集群的每个成员都在重新启动计划中:

节点 1 - 每个月的第一个星期日 1:00am 节点 2 - 每个月的第二个星期日 1:00am

每当这些节点重新启动时,我都会在我的 J2EE 应用程序日志文件中看到以下异常:

org.hibernate.engine.transaction.spi.AbstractTransactionImpl.rollback(AbstractTransactionImpl.java:209)
... 154 more
Caused by: java.sql.SQLRecoverableException: ORA-01089: immediate shutdown in progress - no operations are permitted

                    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:445)
                    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:389)
                    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:382)
                    at oracle.jdbc.driver.T4C7Ocommoncall.processError(T4C7Ocommoncall.java:93)
                    at oracle.jdbc.driver.T4CTTIfun.receive

我们的 DBA 说“我们在本地关闭事务。它应该尝试等待正在运行的事务完成并且不允许新事务。

正如我上面提到的,在 2 个节点中,一次只有一个节点重新启动,考虑到 DBA 的回答。我们的应用程序在重新启动过程中不应阻塞数据库。

我的问题是,为什么我的应用程序会抛出这个异常?为什么我的应用程序正在尝试连接到正在进行关闭的数据库节点?

您的应用程序未尝试连接到正在关闭的节点。关机开始的时候已经连接上了

我假设您的应用程序在中间层维护一个连接池。因此,据推测,就在其中一个节点重新启动之前,您的连接池已打开到两个节点的连接。当 DBA 执行 shutdown transactional 时,允许完成具有活动事务的会话,但连接池中连接到正在关闭的节点的大多数会话此时将没有活动事务。当您从连接池中获取这些连接之一并尝试启动事务时,您将收到此错误。

您很可能想捕获此错误并重新连接,这会导致与剩余节点建立新连接。您遇到的错误是 SQLRecoverableException,因此尝试恢复通常是有意义的。