这是很多问题:)我将尝试完成前面的答案。
Is there a better way to simulate the DB failure?
测试所有案例都很复杂。测试主要情况的一种方法是创建一个JCA连接器(数据库驱动程序是一个JCA连接器)。您可以从将在事务中登记的连接器(第三个参与者)获取连接。然后,连接可能会引发某些错误。
有三个部分协同工作:(1) 应用程序,(2) 应用程序服务器的事务管理器,以及 (3) jca 连接器(所谓的资源适配器)。
连接通过 将自身挂接到事务中。使用自定义 JCA 连接器,您可以向应用程序(在 picutre 中)或应用程序服务器的事务管理器(通过图片中获取)引发异常。您可以在 和 期间引发异常,这与 2 阶段提交期间的错误相对应。ManagedConnection.getXAResource
Connection
XAResource
ManagedConnection
XAResource.prepare
XAResource.commit
请注意,很难控制参与者的兴奋顺序(见此问题)。因此,很容易测试其中一个失败(即您的失败),但很难控制它们的调用顺序。重现 2 阶段提交的所有可能的无效状态很复杂,尤其是在进行优化时。prepare
(我曾经写过一个JCA连接器(http://code.google.com/p/txfs),如果你想要示例代码,周围还有其他连接器。
What happens to the connection object when DB connection goes bad?
Does it retain its value or does it become null?
可以通知事务管理器。其中一个通知是通知它使用此特定连接时发生错误。ManagedConnection
ConnectionEvent.CONNECTION_ERROR_OCCURRED
如其他答案中所述,通常每个事务都有一个关联的托管连接。托管连接将物理连接抽象化,并且您不希望使用太多物理连接。该应用程序仅获取“句柄”(如图所示)。在一个给定事务中获取的句柄都指向同一个托管连接。这是大多数应用服务器支持的优化。Connection
如果托管连接变得无效,则使用它的句柄也会变为无效。但是手柄可以不被“刷新”。事务必须回滚,托管连接将被销毁。当另一个事务启动时,它将与池中的另一个有效托管连接相关联。
What actually happens when application tries to reconnect to DB?
What value does connection object get?
Does it use an existing value from the connection pool?
应用服务器管理托管连接池。如前一段所述,在使用时可能会变坏。但是,如果不加以使用,一个人也可能变坏。例如,池中已使用的托管连接可能会因基础物理连接超时而变得无效。应用服务器通常具有一项功能,用于在开始使用托管连接之前测试该连接是否有效。如果没有,它将尝试池中的另一个托管连接,或创建一个新连接。