web-dev-qa-db-ja.com

JDBCでトランザクションを開始する方法は?

Connection.setTransactionIsolation(int) 警告:

注:トランザクション中にこのメソッドが呼び出されると、結果は実装定義になります。

JDBCでトランザクションをどのように開始しますか?トランザクションを終了する方法は明確ですが、開始方法は明確ではありません。

Connectionがトランザクション内で開始する場合、実装固有の動作を回避するために、トランザクション外でConnection.setTransactionIsolation(int)を呼び出す方法を教えてください。

56
Gili

自分の質問に答える:

  • JDBC接続は、自動コミットモードを有効にして開始します。このモードでは、各SQLステートメントは暗黙的にトランザクションで区切られます。
  • トランザクションごとに複数のステートメントを実行するユーザーは、 auto-commit off をオンにする必要があります。
  • 自動コミットモードを変更すると、現在のトランザクションのコミットがトリガーされます(アクティブな場合)。
  • Connection.setTransactionIsolation() は、自動コミットが有効になっている場合はいつでも呼び出すことができます。
  • 自動コミットが無効になっている場合、 Connection.setTransactionIsolation() はトランザクションの前または後にのみ呼び出すことができます。トランザクションの途中で呼び出すと、未定義の動作が発生します。

ソース:

50
Gili

JDBCは暗黙的にeachトランザクションとの接続で実行するクエリ/更新を区別します。 setAutoCommit(false)を呼び出して自動コミットモードをオフにし、commit()/ rollback()を呼び出してトランザクションの終了を示すことで、この動作をカスタマイズできます。 。擬似コード

try
{
  con.setAutoCommit(false);

   //1 or more queries or updates

   con.commit();
}
catch(Exception e)
{
   con.rollback();
}
finally
{
   con.close();
}

これで、表示したメソッドにタイプがあります。 setTransactionIsolation(int level)である必要があり、トランザクション境界のapiではありません。ある操作によって行われた変更が他の並行操作から見えるようになる方法/時期を管理します。"I" in [〜#〜] acid [〜#〜](http ://en.wikipedia.org/wiki/Isolation_(database_systems))

25

読むことをお勧めします this 表示されます

したがって、setAutoCommit(false)の最初の呼び出しとcommit()の各呼び出しは、トランザクションの開始を暗黙的にマークします。トランザクションは、呼び出すことによってコミットされる前に元に戻すことができます

編集:

JDBCトランザクションの公式ドキュメントを確認してください

接続が作成されると、自動コミットモードになります。つまり、個々のSQLステートメントはトランザクションとして扱われ、実行直後に自動的にコミットされます。 (より正確には、デフォルトでは、実行時ではなく完了時にSQLステートメントがコミットされます。すべての結果セットと更新カウントが取得されると、ステートメントは完了します。ただし、ほとんどの場合、ステートメントは実行された直後に完了するため、コミットされます。)

2つ以上のステートメントをトランザクションにグループ化する方法は、自動コミットモードを無効にすることです。これは次のコードで示されています。 conはアクティブな接続です。

con.setAutoCommit(false);

ソース: JDBC Transactions

18
Necronet

実際、 JDBCチュートリアルのこのページ の方が読みやすいでしょう。
接続を取得し、分離レベルを設定し、AMDのアップデートを行ってから、コミットまたはロールバックします。

9
Romain Hippeau

接続を「setAutoCommit(true)」モードのままにしたいが、それでもトランザクションが必要な場合、最初は手動でトランザクションを実行できます。

 try (Statement statement = conn.createStatement()) {
      statement.execute("BEGIN");
      try {
        // use statement ...
        statement.execute("COMMIT");
      }
      catch (SQLException failure) {
        statement.execute("ROLLBACK");
      }
  }
3
rogerdpack

たぶんこれはあなたの質問に答えるでしょう:あなたは接続ごとに1つのトランザクションしか持つことができません。自動コミットがオン(デフォルト)の場合、選択、更新、削除のたびにトランザクションが自動的に開始され、コミット(またはロールバック)されます。自動コミットをオフに設定すると、「新しい」トランザクションが開始されます(つまり、コミットまたはロールバックは自動的に行われません)。いくつかのステートメントの後、コミットまたはロールバックを呼び出して、現在のトランザクションを終了し、新しいトランザクションを自動的に開始できます。純粋なJDBCの1つのJDBC接続で2つのトランザクションをアクティブに開くことはできません。

3

トランザクションには次のメソッドを使用できます。

  1. conのような接続オブジェクトを作成する必要があります
  2. con.setAutoCommit(false);
  3. あなたの質問
  4. すべてが真の場合con.commit();
  5. else con.rollback();
2
Manochehr