Фиксация при открытии новой транзакции внутри транзакции

#java #jakarta-ee #transactions #ejb-3.0 #weblogic11g

#java #джакарта-ee #транзакции #ejb-3.0 #weblogic11g

Вопрос:

Использование Ejb3.0, Weblogic 11g, JDBC

Я вызываю метод, который выполняется удаленно в другом EAR развертывания.

Вызываемый метод в удаленном развертывании, но он снабжен аннотацией @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)

проблема в том, что вся логика, которую я выполняю в базе данных перед вызовом удаленного метода, не будет зафиксирована до завершения удаленного метода.

Что я хотел бы сделать, так это зафиксировать, чтобы логика «до» выполнялась» и когда я вернусь после удаленного вызова, чтобы продолжить нормально.

Есть идеи?

Некоторый код для объяснения:

 @CallByReference
@Stateless(mappedName = "ejb/OperatorProccessBean")
@Local({ OperatorProccessBeanLocal.class })
@Remote({ OperatorProccessBeanRemote.class })
public class OperatorProccessBean implements OperatorProccessBeanLocal,  
 OperatorProccessBeanRemote
{   

...

   SBNDispatchBeanRemote SBNDispatchBean = (SBNDispatchBeanRemote) context.lookup("ejb/SBNDispatchBean#com.mirs.sbn.dispatch.SBNDispatchBeanRemote");
    if (SBNDispatchBean == null)
    {
            logger.error(TAG   " SBNDispatchBean is null");

    }
    else
    {
         //until here I want all my data to be commited without waiting for the upcoming remote method to finish
         SBNDispatchBean.updateSubscriberInBlockingList(...);
    }
...
 }
  

Теперь метод updateSubscriberInBlockingList() снабжен комментарием

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)

я хочу, чтобы данные были зафиксированы до вызова этого метода.

Заранее спасибо, Рэй.

Ответ №1:

Теперь метод updateSubscriberInBlockingList() аннотируется с помощью @TransactionAttribute(тип TransactionAttributeType.ТРЕБУЕТСЯ СОЗДАТЬ новую)

Я хочу, чтобы данные были зафиксированы до вызова этого метода.

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

Это поведение не настраивается, поскольку ожидается, что контейнер EJB и диспетчер транзакций JTA будут придерживаться поведения, указанного в спецификации JTA, которая является производной от модели транзакций X / Open DTP. В модели X / Open DTP, если запускается новая транзакция, в то время как выполняется другая, текущая транзакция приостанавливается и возобновляется в более поздний момент времени. Следует отметить, что ни одна модель транзакции, возможно (я не изучил все), не допускает фиксации текущей транзакции и запуска новой. Я видел только вложенные транзакции или приостановленные транзакции, поддерживаемые в различных моделях обработки транзакций.

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

Комментарии:

1. «Если вы хотите, чтобы работа была зафиксирована, вы должны полностью завершить существующий контекст транзакции», как вы это делаете?

2. Вы должны вызывать updateSubscriberInBlockingList метод только после завершения выполнения текущего транзакционного метода. Транзакции всегда связаны с потоками. Если диспетчер транзакций JTA (TM) обнаружит, что транзакция связана с потоком, он приостановит существующую и запустит новую транзакцию. Следовательно, у вас не должно быть транзакции, связанной с текущим потоком, если вам нужно этого добиться.

3. Да .. но проблема в том, что я должен выполнить этот метод ()updateSubscriberInBlockingList) и только после его завершения продолжить работу с моим кодом. как я завершу выполнение текущего транзакционного метода?

4. Короткий ответ, учитывая это требование, заключается в том, что вы не можете. Длинный ответ — это то, что я изложил выше. X / Open DTP, JTA, JTS и EJB просто не позволят использовать эту модель программирования. Кроме того, почему приостановка транзакций может вызвать какие-либо проблемы в этом случае?

5. Потому что у меня был случай, когда вторая транзакция выполнила множество откатов и получила время ожидания транзакции, а фиксация не была выполнена. это привело к тому, что вызывающая транзакция не выполнила «фиксацию» . и я предполагаю, что это потому, что «дочерняя» транзакция не была зафиксирована.

Ответ №2:

Поместите логику «перед удаленным вызовом» в отдельный метод bean, также снабженный аннотацией REQUIRE_NEW . Таким образом, у вас будет три транзакции :

  • один для основного метода (но который ничего не будет делать, пока не будет выполнен удаленный вызов);
  • один для логики перед удаленным вызовом;
  • один для удаленного вызова.