JtaTransaction localStatus在创建后回滚

时间:2014-06-25 14:33:42

标签: java hibernate jta

我正在创建一个休眠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?

1 个答案:

答案 0 :(得分:0)

Hibernate将本地作为JTA事务抽象为自己的抽象层,因此我不明白为什么你必须编写这样的低级事务处理代码。

在Java EE中,您可以使用应用服务器来管理事务,在独立应用程序Bitronix + Spring中也可以完成工作。

虽然您可以设法编写自己的事务管理逻辑,但我总是建议人们重用已有的事务。 Xa / JTA和Hibernate需要广泛的知识才能无缝工作。

更新1

两个不同的线程不应该使用相同的用户事务,您应该为每个线程使用不同的事务。