Hibernate 4.1.9(最新的最终版本)报告“不支持嵌套事务”

Posted

技术标签:

【中文标题】Hibernate 4.1.9(最新的最终版本)报告“不支持嵌套事务”【英文标题】:Hibernate 4.1.9 (latest final build) reporting `nested transactions not supported` 【发布时间】:2013-01-06 17:23:37 【问题描述】:

我得到了一个

org.hibernate.TransactionException: nested transactions not supported
at    org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:152)
at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1395)
at com.mcruiseon.server.hibernate.ReadOnlyOperations.flush(ReadOnlyOperations.java:118)

引发该异常的代码。我从一个无限运行的线程调用flush,直到有数据要刷新。

public void flush(Object dataStore) throws DidNotSaveRequestSomeRandomError 
    Transaction txD;
    Session session;
    session = currentSession();
    // Below Line 118 
    txD = session.beginTransaction();
    txD.begin() ;
    session.saveOrUpdate(dataStore);
    try 
        txD.commit();
        while(!txD.wasCommitted()) ;
     catch (ConstraintViolationException e) 
        txD.rollback() ;
        throw new DidNotSaveRequestSomeRandomError(dataStore, feedbackManager);
     catch (TransactionException e) 
        txD.rollback() ;
      finally 
        // session.flush();
        txD = null;
        session.close();
    
    // mySession.clear();

编辑: 我在独立线程中调用刷新,因为数据存储列表包含数据。从我所看到的情况来看,它是对刷新的同步操作调用,因此理想情况下,刷新不应该在事务完成之前返回。我希望这样是我最不希望的。由于它是一个独立的线程来完成它的工作,我只关心它刷新是一个同步操作。现在我的问题是, txD.commit 是异步操作吗?它是否在该事务有机会完成之前返回。如果是,有没有办法在事务完成之前提交“等待”?

        public void run() 
        Object dataStore = null;
        while (true) 
            try 
                synchronized (flushQ) 
                    if (flushQ.isEmpty())
                        flushQ.wait();
                    if (flushQ.isEmpty()) 
                        continue;
                    
                    dataStore = flushQ.removeFirst();
                    if (dataStore == null) 
                        continue;
                    
                
                try 
                    flush(dataStore);
                 catch (DidNotSaveRequestSomeRandomError e) 
                    e.printStackTrace();
                    log.fatal(e);
                
             catch (HibernateException e) 
                e.printStackTrace();
             catch (InterruptedException e) 
                e.printStackTrace();
            
        
    

编辑 2:添加了while(!txD.wasCommitted()) ;(在上面的代码中),但我仍然觉得这该死的nested transactions not supported。事实上,由于这个异常,表也没有写入记录。与表的类型有关吗?我的所有表都有 INNODB?

【问题讨论】:

我认为您开始交易两次,您可以尝试删除第二条语句txD = session.beginTransaction(); txD.begin() ; 已删除,结果相同。嵌套事务不支持异常。 好的,删除这两行并使用session.getTransaction() 获取事务实例并告诉我们。 顺便说一句,我刚刚在某处读到 begin 创建了一个新事务,而 getTransation 重用了旧事务。试试getTransaction(),几分钟后报告。 谢谢,您的提示帮助我进行了更多搜索并获得了适当的答案。 【参考方案1】:

终于修复了nested transaction not supported 错误。对代码所做的更改是

    if (session.getTransaction() != null
            && session.getTransaction().isActive()) 
        txD = session.getTransaction();
     else 
        txD = session.beginTransaction();
    

    //txD = session.beginTransaction();
    // txD.begin() ;
    session.saveOrUpdate(dataStore);
    try 
        txD.commit();
        while (!txD.wasCommitted())
            ;
    

以上代码也归功于Venkat。我没有找到 HbTransaction,所以只使用了 getTransaction 和 beginTransaction。它奏效了。

由于here 上的建议,我还对休眠属性进行了更改。我将这些行添加到了 hibernate.properties。仅此一项并不能解决问题。但我要把它留在那里。

hsqldb.write_delay_millis=0
shutdown=true

【讨论】:

嗨,正如你所说..在我的情况下,我根本没有打开Trasaction 我确定我只打开一次Transaction 但我仍然得到NestedTrasactionException .. 可能是什么原因 Hibernate 非常敏感,编码时不要使用 java 基础。如果它有效,那就让它吧。上面的代码来自生产并且一直在工作。我只能说这些 好的,谢谢.. 我也会用你的代码来处理我的情况。【参考方案2】:

您可能在调用此方法之前已经开始了事务。

这应该是封闭事务的一部分,因此您不应该开始另一个;或者它不应该是封闭事务的一部分,因此您应该打开一个新会话和一个新事务,而不是使用当前会话。

【讨论】:

编辑了我的问题以添加更多细节和清晰度。请指教。 为了保持整洁,我已经提出了我的答案,但为了公平起见,我接受你的答案,因为你暗示我找到了正确的解决方案。谢谢。 @JB Nizet 嗨,正如你所说.. 就我而言,我根本没有打开 Trasaction 我确定我只打开一次 Transaction 但我仍然得到 NestedTrasactionException .. 什么可能是这个原因

以上是关于Hibernate 4.1.9(最新的最终版本)报告“不支持嵌套事务”的主要内容,如果未能解决你的问题,请参考以下文章

hibernate4.3 无法获取数据库最新值

hibernate 4.3 在使用获取数据获取不到数据库中最新变更的数据问题解决

使用瀚高数据库hibernate方言报错

使用瀚高数据库hibernate方言报错

wildfly 10上使用最新的 Hibernate ORM OGM

spring4整合hibernate5以及出现的问题解决办法