3

我得到一个

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)

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

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 吗?

4

2 回答 2

8

终于修复了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。有效。

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

hsqldb.write_delay_millis=0
shutdown=true
于 2013-01-07T06:32:58.577 回答
3

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

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

于 2013-01-06T17:29:09.333 回答