TransactionAttribute.REQUIRES_NEW не запускает новую транзакцию в EJB-компоненте с использованием транзакции, управляемой контейнером - PullRequest
0 голосов
/ 28 июня 2018
@Singelton
public Class className {

     @Resource
     private TransactionSynchronizationRegistry tsr;

    @Resource 
    private Transaction 

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public method_A () {

         System.out.println(tsr.getTransactionStatus()); // prints 0 

         method_call_which_throw_persistence_exception(); 

         System.out.println(tsr.getTransactionStatus());  // prints 1

         method_B();

    }

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public method_B () {
          System.out.println(tsr.getTransactionStatus());  // prints 1
    }


} 

Примечание: статус транзакции 0 = активен. Состояние транзакции 1 = отмечено ForRollback

Поскольку я прикрепил приведенный выше код, в Ejb singelton bean-компоненте, который использует транзакцию, управляемую контейнером, присутствуют 2 метода. Запускается метод method_A, для которого транзакция транзакции имеет значение REQUIRED, поэтому TransactionSynchronizationRegistry печатает состояние транзакции как 0 при запуске. После вызова метода, который генерирует исключение, статус транзакции автоматически становится равным 1. Но когда method_B, который имеет атрибут транзакции как REQUIRES_NEW, по-прежнему вызывается, TransactionSynchronizationRegistry печатает 1. Насколько я понимаю, он должен начать новую транзакцию, а статус транзакции должен отображаться как 0 в method_B?

1 Ответ

0 голосов
/ 30 июня 2018

Прямой вызов метода компонента из метода того же компонента не проходит через перехватчик транзакции и, следовательно, проверка атрибута транзакции не выполняется.

Есть 2 способа решить эту проблему:

@Resource
private ManagedExecutorService mes;


....
mes.execute(()->method_B());
....

Это пройдет через перехватчик / прокси, а также, находясь в другом потоке, автоматически запустит новую транзакцию. недостатком здесь является то, что если новая транзакция завершится неудачно, транзакция в method_A не будет откатываться, поскольку они находятся в разных потоках

...