【问题标题】:What happened when I call UserTransaction.begin()?当我调用 UserTransaction.begin() 时发生了什么?
【发布时间】:2020-07-14 07:41:12
【问题描述】:

假设我有这样的代码:

public class Test{
    DataSource ds1;
    DataSource ds2;
    DataSource ds3;
    UserTransaction userTransaction;
    ...
    public void test(){
        userTransaction.begin();
        ds1.getConnection().createStatement().execute(...);
        ds2.getConnection().createStatement().execute(...);
        userTransaction.commit();
    }
}

UserTransaction 如何知道我将使用哪个 DataSource?

因为它之前没有将 DataSource 注册到 UserTransaction。

在我看来,JTA 是基于 XA 事务的。像这样工作:

XADataSource xaDataSource1;
XADataSource xaDataSource2;

XAResource xaResource1 = xaDataSource1.getXAResource();
XAResource xaResource2 = xaDataSource2.getXAResource();

Xid xid = ...

xaResource1.start(xid);
xaResource2.start(xid);

xaDataSource1.getXAConnection().getConnection().createStatement().execute(...);
xaDataSource2.getXAConnection().getConnection().createStatement().execute(...);

xaResource1.commit(xid,...);
xaResource2.commit(xid,...);

那么,JTA 的 userTransaction.begin() 是否为其所有托管的 DataSource 调用 xaResource.start(xid)?

或者说它是如何实现这个机制的?

【问题讨论】:

    标签: java transactions distribution jta


    【解决方案1】:

    在容器环境中,所有事务性资源(您的 XAResources)必须事先由应用程序征用。这种登记允许在事务启动时通知参与的资源管理器并执行实际的提交步骤。

    提供登记,如 JTA 规范 (https://jcp.org/en/jsr/detail?id=907) 所述:

    对于应用程序使用的每个资源,应用程序服务器调用 enlistResource 方法并指定标识正在使用的资源的 XAResource 对象。

    enlistResource 请求导致事务管理器通知资源管理器开始将事务与通过相应资源执行的工作相关联 - 通过调用 XAResource.start 方法。事务管理器负责将其 XAResource.start 方法调用中的适当标志传递给资源管理器。 (...)

    当由用户 (UserTransaction) 或容器启动时,根据规范,事务 ID 与当前线程相关联。不仅如此,该实现还可以协调与另一个远程事务服务的通信,因此所有这些服务都与同一个事务相关联。

    因此,在回答您的问题时,UserTransaction 知道资源,因为它们应该事先由容器注册和控制。我认为具体的实现可能或多或少是广泛的 - v.g.,CDI 容器可能只将事务托管 bean 的注入资源与其事务相关联,而不是应用程序可用的所有其他 XAResources,或者可以注册所有这些以确保完整性。

    【讨论】:

    • 但是我之前只将 XADataSource 注册到了容器中。容器是否拦截了 xaDataSource.getXAConnection().getXAResource() 并将 XAResource 注册到容器中还是什么?
    • 简单地回答,是的,它按照JTA spec 的第 3.3.1 项的定义执行此操作。应用程序服务器负责登记 em delist 资源,基本上只要它识别出注册的资源支持 XA 并链接到使用给定资源的应用程序(或 EJB,或 CDI bean),就会调用您引用的方法一笔交易。
    • 感谢您的回复,对您有很大帮助
    猜你喜欢
    • 2018-06-07
    • 2016-11-11
    • 1970-01-01
    • 2022-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-21
    相关资源
    最近更新 更多