Java 自动将资源登记/清除到新Tx中的方法?

Java 自动将资源登记/清除到新Tx中的方法?,java,transactions,jta,Java,Transactions,Jta,因为TransactionManager无法注册XAResource管理器,因此它可以在将来的事务中登记XAResources 解决此问题的唯一方法是包装感兴趣的服务接口的句柄。 接口上的每个方法都执行以下操作: 检查是否存在发送 确定此tx的句柄是否正确 如果尚未参与,请使用Transaction.enlist(XAResource)登记其XAResource 注册回调以使用Transaction.registerSynchronization(同步)启用清理 这似乎是一个合理的策略吗?这

因为TransactionManager无法注册XAResource管理器,因此它可以在将来的事务中登记XAResources

解决此问题的唯一方法是包装感兴趣的服务接口的句柄。 接口上的每个方法都执行以下操作:

  • 检查是否存在发送
  • 确定此tx的句柄是否正确
  • 如果尚未参与,请使用Transaction.enlist(XAResource)登记其XAResource
  • 注册回调以使用Transaction.registerSynchronization(同步)启用清理

这似乎是一个合理的策略吗?

这是一个合理的初稿,但有一些微妙之处需要注意。自己解决这些问题很难——最好为代码编写一个资源适配器,让JCA处理事务管道,这是大多数数据库和消息队列驱动程序所做的

  • 仅仅因为存在tx上下文,这并不意味着您可以使用tx登记。特别是,如果tx标记为rollback only,则规范要求EnglistResource引发RollbackException

  • 仅仅因为上下文存在并且在您检查它时tx有一个有效状态,这并不意味着它在方法调用的整个生命周期内保持存在或有效。您可以获得竞争条件,在这种竞争条件下,当您的业务逻辑仍在运行时,TM调用资源回滚

  • 由于XA的C传统,XAResource对象实例、服务接口实例和事务之间的关系不是特别优雅。在面向连接的API(如JDBC)中,每个连接通常有一个XAResource,该XAResource实例可能管理多个tx上下文。对于无连接API,您可以使用其他可能更简单的模式

  • 不需要同步。也不一定需要同步,因为同步是不稳定的,所以在崩溃恢复情况下不会调用清理。最好在非启发式情况下清理提交/回滚