EJB 3.0 CMP Транзакция после отката - PullRequest
2 голосов
/ 09 декабря 2011

У меня проблемы с управлением транзакциями в EJB3.0. Что я хочу сделать, так это записать ошибку в базу данных на случай возникновения исключения.

Для этой цели у меня есть 2 компонента без сохранения состояния: Bean A и Bean B.

Бин A выполняет следующие действия:

  1. сохранить что-нибудь
  2. вызов Bean B для регистрации ошибки при необходимости

На шаге 1 сохранение в основном выполняется методом EntityManager#merge(-). На шаге 2 я поместил следующие строки вверху Bean B:

@Stateless(name = "ErrorLogDAO", mappedName = "ErrorLogDAO")
@Remote
@Local
@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class ErrorLogDAOBean {...}

Однако, когда в методе сохранения возникает исключение, я его перехватываю, а затем вручную вызываю метод ctx.setRollBackOnly(), и после этого я вызываю ErrorLogDAOBean, который вставляет журнал ошибок в БД. Но журнал ошибок не вставляется, и я получаю следующую ошибку:

javax.transaction.TransactionRolledbackException: EJB Exception:: weblogic.transaction.internal.AppSetRollbackOnlyException at weblogic.transaction.internal.TransactionImpl.setRollbackOnly (TransactionImpl.java:551) в weblogic.transaction.internal.TransactionManagerImpl.setRollbackOnly (TransactionManagerImpl.java:319) в weblogic.transaction.internal.TransactionManagerImpl.setRollbackOnly (TransactionManagerImpl.java:312) в org.eclipse.persistence.transaction.JTATransactionController.markTransactionForRollback_impl (JTATransactionController.java:145) в org.eclipse.persistence.transaction.AbstractTransactionController.markTransactionForRollback (AbstractTransactionController.java:196) в org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.rollbackTransaction (UnitOfWorkImpl.java:4486) в org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabase (UnitOfWorkImpl.java:1351) в org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.commitToDatabase (RepeatableWriteUnitOfWork.java:468) в org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithPreBuiltChangeSet (UnitOfWorkImpl.java:1439) в org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.writeChanges (RepeatableWriteUnitOfWork.java:316) в org.eclipse.persistence.internal.jpa.EntityManagerImpl.flush (EntityManagerImpl.java:527) ....

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

Есть идеи?

UPDATE

Bean A код:

@TransactionManagement(value = TransactionManagementType.CONTAINER)
@TransactionAttribute(value = REQUIRED)
public class WMServiceBOBean {

public void saveInBeanA {

     int errorCode = save();

     if (errorCode != SUCCESS)
     { 
   ClassX.logError();
   ctx.setRollbackOnly();
   return errorCode;
     }
   }
}

Код X класса:

public class classX
{
 ...
 public void logError()
 {
   ErrorLog e = new ErrorLog;
   BeanB beanB = //Local lookup of Bean B
   beanB.insertErrorLog (e);
 }
 ...
}

BEAN B код:

@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class ErrorLogDAOBean
{
 ...
 public void insertErrorLog (ErrorLog e)
 {
   merge (e);
 }
 ...
}

1 Ответ

1 голос
/ 15 декабря 2011

Я наконец-то выяснил проблему.

Вот проблема, когда я искал ErrorLogBean, я создавал новый Диспетчер постоянства.Когда транзакция была помечена для отката, процесс получения нового PM был неудачным.Я знаю, что не имеет смысла приобретать нового менеджера постоянства, но это было частью теста, который мы проводим.

Спасибо Петру за вашу помощь в этом!

...