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 に答える