2015-01-14 3 views
0

У меня есть следующий код, который сохраняет пользователя и отправляет сообщение JMS. В настоящее время im wraping saveUserSendMessage с UserTransaction. Когда транзакция вложен, я получаю исключение в ejb. Что я делаю ниже, чтобы сделать вложенную транзакцию возможной?Вложенные транзакции в транзакции ejb sessionbean - bean managed

@Resource(mappedName = "java:/JmsXA") 
private static QueueConnectionFactory queueConnectionFactory; 

@Resource(mappedName = "EjbQueueJndi") 
private static Queue queueProp; 

@PersistenceContext(unitName = "ejbPersistanceunit") 
private EntityManager em; 

@Resource 
UserTransaction ut; 

@Override 
public boolean saveUserSendMessage(String name, String email, int age, 
     boolean arg3) throws Exception { 

    UserTransaction xact = ut; 
    xact.begin(); 

    saveUser(name, email, age); 
    sendMessage("Successfully saved the user"); 
    try { 
     if (arg3) 
      throw new Exception("Unsuccessfull"); 
     xact.commit(); 
    } catch (Exception e) { 
     xact.rollback(); 
     throw e; 
    } 
    return true; 
} 

@Override 
public boolean saveUser(String name, String email, int age) 
     throws Exception { 
    try { 
     ut.begin(); 
     UserEntity ue = new UserEntity(); 
     ue.setAge(age); 
     ue.setEmail(email); 
     ue.setName(name); 
     em.persist(ue); 
     ut.commit(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     throw e; 
    } 
    return true; 
} 

Исключение я получаю:

15:51:04,127 ERROR [STDERR] javax.transaction.NotSupportedException: BaseTransaction.checkTransactionState - [com.arjuna 
.ats.internal.jta.transaction.arjunacore.alreadyassociated] [com.arjuna.ats.internal.jta.transaction.arjunacore.alreadya 
ssociated] thread is already associated with a transaction! 
+0

Я не думаю, что вы можете это сделать, используя транзакции, управляемые Bean. Это возможно в транзакциях, управляемых контейнером, но даже тогда не в рамках одного и того же метода. – EdH

+0

Вы имеете в виду тот же класс?/ – Zeus

+1

Я имел в виду метод. Использование CMT и метод с RequiresNew должны поддерживать вложенные транзакции, но даже с CMT весь код, выполняемый в этом методе, будет находиться в одной транзакции. Я думаю, возможно, если один и тот же объект вызывается через уровень сервиса, что если он вызывает другой метод с собственным определением RequiresNew, он может использовать новую транзакцию. Но все это CMT, и в литературе не указано, что для BMT возможно что-либо из этого. – EdH

ответ

2

Java EE не поддерживает вложенные транзакции. Единственное, что он поддерживает, - это приостановление транзакции, запуск несвязанной транзакции и возобновление первой транзакции.

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

Вы действительно хотите это сделать? Вероятно, лучше всего просто выполнить логику в транзакции, управляемой контейнером.

Смежные вопросы