我在EJB3.0中遇到了一些事务管理问题。我想要做的是在发生异常时将错误记录到数据库中。
为此,我有2个无状态bean:Bean A
和Bean B
。
Bean A执行以下操作:
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 {...}
但是,当在save方法中发生异常时,我正在捕获它,然后我手动调用ctx.setRollBackOnly()
方法,之后我调用ErrorLogDAOBean
将错误日志插入到D B。但是没有插入错误日志,我得到的错误是:
javax.transaction.TransactionRolledbackException:EJB异常:: 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) ....
我对事务管理逻辑非常熟悉,基于上面的代码,我假设我已经覆盖了这个,但似乎没有。
有什么想法吗?
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);
}
...
}
答案 0 :(得分:1)
我终于找到了问题。
这是问题所在,当查找ErrorLogBean时,我正在实例化一个新的Persistence Manager。当事务被标记为回滚时,获取新PM的过程失败。我知道获得一个新的持久性管理器是没有意义的,但它是我们正在进行的测试的一部分。
感谢Piotr为您提供的所有帮助!