Что произошло, когда я вызвал UserTransaction.begin ()? - PullRequest
0 голосов
/ 14 июля 2020

Допустим, у меня есть такой код:

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,...);

Итак, вызывает ли userTransaction.begin () JTA xaResource.start (xid) для всего управляемого DataSource?

Или как он реализует этот механизм?

1 Ответ

1 голос
/ 15 июля 2020

В среде контейнера все транзакционные ресурсы (ваши XAResources) должны быть предварительно включены в качестве таковых приложением. Это присоединение позволяет сообщить участвующему менеджеру ресурсов, когда транзакция запущена, и выполнить фактические шаги фиксации.

При условии, что зачисление, как указано в спецификации JTA (https://jcp.org/en/jsr/detail?id=907):

Для каждого ресурса, используемого приложением, сервер приложений вызывает метод enlistResource и указывает объект XAResource, который идентифицирует используемый ресурс.

Результатом запроса enlistResource является диспетчер транзакций, информирующий диспетчер ресурсов, чтобы начать связывать транзакцию с работой, выполняемой через соответствующий ресурс - путем вызова метода XAResource.start. Диспетчер транзакций отвечает за передачу соответствующего флага в вызове метода XAResource.start диспетчеру ресурсов. (...)

Идентификатор транзакции связан с текущим потоком, согласно спецификации c, при запуске пользователем (UserTransaction) или контейнером. Более того, реализация может координировать обмен данными с другими службами удаленных транзакций, чтобы все они были связаны с одной и той же транзакцией.

Итак, отвечая на ваши вопросы, UserTransaction знает о ресурсах, потому что они должны быть предварительно зарегистрированы и контролироваться контейнером. Я думаю, что конкретная реализация c может быть более или менее широкой - vg , контейнер CDI может связывать только внедренные ресурсы управляемого bean-компонента транзакции со своей транзакцией, а не все другие источники XAR, доступные для приложения. , или можете зарегистрировать их все для полноты.

...