一尘不染

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

hibernate

我正在

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


阅读 292

收藏
2020-06-20

共1个答案

一尘不染

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

要么这应该是封闭事务的一部分,所以您不应该启动另一事务。否则它不应该是封闭事务的一部分,因此您应该打开一个新会话和一个新事务,而不要使用当前会话。

2020-06-20