我正在创建一个休眠Session
并尝试启动一个新的[Jta]事务。但是,无法启动事务,因为后台使用的JtaTransaction似乎已回滚。
这就是我正在做的事情。
Session session = sessionFactory.openSession();
CustomSessionWrapper dpSession = new CustomSessionWrapper(session, this);
if (!session.isClosed() && !session.getTransaction().isActive()) {
session.beginTransaction();
}
然而,在调用beginTransaction
后,事务仍然无效。当我调试beginTransaction
方法时,我来到doBegin
的{{1}}方法(我不会覆盖此方法,我只是发布此方法的原始代码)。
JtaTransaction
@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()
并且未启动任何交易。有谁知道我怎么解决这个问题?
UPDATE 1 (您可以跳过,因为这是一个错误,请参阅更新2)
我发现有两个线程,一个使用主会话,另一个使用较小的会话进行日志记录。主会话(和事务)打开的时间较长,因此基本上直到操作完成。似乎Status.STATUS_ROLLEDBACK
始终返回相同的locateUserTransaction
。这意味着主会话打开此userTransaction并且其中一个side transaction提交/回滚该事务。有谁知道该做什么,以便检索不同的交易?
更新2
我发现我没有两个线程,只有一个线程并行打开两个会话。然后每个会话都应该打开自己的事务,尽管两者都获得相同的UserTransaction。我如何告诉hibernate每个会话应该获得自己的[User] Transaction?
答案 0 :(得分:0)
Hibernate将本地作为JTA事务抽象为自己的抽象层,因此我不明白为什么你必须编写这样的低级事务处理代码。
在Java EE中,您可以使用应用服务器来管理事务,在独立应用程序Bitronix + Spring中也可以完成工作。
虽然您可以设法编写自己的事务管理逻辑,但我总是建议人们重用已有的事务。 Xa / JTA和Hibernate需要广泛的知识才能无缝工作。
更新1
两个不同的线程不应该使用相同的用户事务,您应该为每个线程使用不同的事务。