[英]JtaTransaction localStatus rolled back after creation
我正在创建一个休眠Session
并尝试启动一个新的JTransaction。 虽然,事务无法启动,因为在后台使用的JtaTransaction似乎已回滚。
这是我在做什么。
Session session = sessionFactory.openSession();
CustomSessionWrapper dpSession = new CustomSessionWrapper(session, this);
if (!session.isClosed() && !session.getTransaction().isActive()) {
session.beginTransaction();
}
但是,在调用beginTransaction
之后,该事务仍未激活。 当我调试beginTransaction
方法时,我来到了JtaTransaction
的doBegin
方法(我没有重写此方法,我只是发布了该方法的原始代码)。
@Override
protected void doBegin() {
LOG.debug( "begin" );
userTransaction = locateUserTransaction();
try {
if ( userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION ) {
userTransaction.begin();
isInitiator = true;
LOG.debug( "Began a new JTA transaction" );
}
}
catch ( Exception e ) {
throw new TransactionException( "JTA transaction begin failed", e );
}
}
userTransaction.getStatus()
返回Status.STATUS_ROLLEDBACK
并且不启动任何事务。 有谁知道我该如何解决?
UPDATE 1 (您可以跳过此操作,因为那是一个错误,请参阅UPDATE 2)
我发现有两个线程,一个使用主会话,另一个使用较小的会话进行日志记录。 主会话(和事务)的打开时间较长,因此基本上直到操作完成为止。 似乎locateUserTransaction
总是返回相同的userTransaction
。 这意味着主会话打开此userTransaction,并且副事务之一提交/回滚该事务。 有谁知道该怎么做才能检索到不同的交易?
更新2
我发现我没有两个线程,只有一个线程可以并行打开两个会话。 然后,每个会话都应打开自己的事务,尽管它们都获得相同的UserTransaction。 我该如何告诉休眠每个会话应获得自己的[User] Transaction?
Hibernate在其自己的抽象层之后将本地和JTA事务都抽象出来,因此我不明白为什么必须编写这样的低级事务处理代码。
在Java EE中,您可以使用应用程序服务器来管理事务,而在独立的应用程序中,Bitronix + Spring也可以完成工作。
尽管您可以设法编写自己的事务管理逻辑,但是我始终建议人们重用他们已经可用的东西。 Xa / JTA和Hibernate需要广泛的知识才能无缝地工作。
更新1
两个不同的线程不应该使用相同的用户事务,您应该为每个线程使用不同的事务。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.