16

プールからデータベース接続 ( conn) を取得しました。

autocommitその接続でそれが TRUE であると仮定します。

設定しましconn.setautocommit(false)た。

その後、いくつかのステートメントを更新した後、最終的conn.commit()/conn.rollback()に完了しました。

setautocommit(true)以前の接続状態に戻すには、明示的にコードを実行する必要がありますか?

または本質的commit()\rollback()に設定されますか?setautocommit(true)

4

3 に答える 3

12

それは、その接続をどこから取得したかによって異なります。自分で接続を作成した場合は、自動コミットの状態を復元する必要はありません。

データ ソースから取得した場合は、状態を元の状態復元する必要があります。これは、データ ソースがプール内の接続を保持し、次のコードが設定内容を予期しない可能性があるためです。

commit()自動コミットの値には影響しません。commit()自動コミットを有効にすると、実行する各ステートメントの後に JDBC ドライバーが確実に呼び出されます。commit()好きなだけ何度でも呼び出すことができますが、何の効果もありません (ただし、rollback()常に希望どおりになるとは限りません)。

[編集]自動コミットの処理方法は、接続プールによって異なります。dbcpには、接続を提供する前に自動コミットをオフにする構成オプションがあります。c3p0は、プールに戻ったときに接続をロールバックします。接続プールの仕組みに関するドキュメントをお読みください。

どのプールが使用されているかわからない場合、安全な解決策はfalse、接続を取得するたびに自動コミットを設定し、例外が発生した場合は接続をロールバックすることです。ラッパーを書くことをお勧めします:

public <T> T withTransaction( TxCallback<T> closure ) throws Exception {
    Connection conn = getConnection();
    try {
        boolean autoCommit = conn.getAutoCommit();
        conn.setAutoCommit(false);

        T result = closure.call(conn); // Business code

        conn.commit();
        conn.setAutoCommit(autoCommit);
    } catch( Exception e ) {
        conn.rollback();
    } finally {
        conn.close();
    }
}

このコードは接続を正しく処理するので、ビジネス コードでこれについて心配する必要はもうありません。

于 2012-09-13T08:34:27.170 に答える