最終更新 :はい、autoCommitを複数回変更できます。また、発見したステートメントでcommit/rollbackコマンドを使用して回避することもできます。私のアドバイスは、autoCommitをfalseに設定したままにし、必要な場所で常にトランザクションを使用することです。
私はPostgresとOracleも使用しており、autocommit =trueでトランザクションを管理できないため、常にautocommit=falseを使用しています
テスト時に自動コミットを変更できますが、単一のステートメントであっても、トランザクションを明示的に管理することをお勧めします。
Spring(またはGuice)のようなフレームワークを使用できる場合は、AOPを介して行われるトランザクション管理があり、コミットとロールバックの指示に煩わされる必要はありません。
Oracleでは、コミット時間はコミットされるデータの量に依存せず、(機能要件に関して)より高い頻度でコミットすることもパフォーマンスを低下させる可能性があります。
更新 :あなたのコメントから、Postgresは自動コミットでトランザクション境界を尊重すると述べています。ここでの動作を再現することはできません。単純なテストケースです:
package test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestPostgresAutocommit {
public static void main(String[] args) throws Exception {
Connection connection= DriverManager.getConnection("jdbc:postgresql://pgdev/dbxxx","xxx","xxx");
connection.setAutoCommit(true);
Connection connection2= DriverManager.getConnection("jdbc:postgresql://pgdev/dbxxx","xxx","xxx");
connection2.setAutoCommit(true);
Statement statement=connection.createStatement();
for (int i=0; i<10; i++) {
statement.execute("insert into test_gc(col1,col2) values ("+ i + "," + "'" + i + "')");
}
statement.close();
countElements(connection2);
statement=connection.createStatement();
statement.execute("delete from test_gc");
statement.close();
statement=connection.createStatement();
statement.execute("begin");
statement.close();
statement=connection.createStatement();
for (int i=0; i<10; i++) {
statement.execute("insert into test_gc(col1,col2) values ("+ i + "," + "'" + i + "')");
}
connection.rollback();
countElements(connection2);
}
private static void countElements(Connection connection2) throws Exception {
Statement statement2=connection2.createStatement();
ResultSet rs=statement2.executeQuery("select count(*) from test_gc");
rs.next();
System.out.println("row num in table=" + rs.getInt(1));
rs.close();
statement2.close();
}
}
プログラムは例外でロールバックに失敗します:
したがって、autoCommitがtrueの場合、トランザクションを管理することはできません。何か違うものを見つけましたか?
アップデートII :コメントのデータを反映していると思うこのコードでも、例外が発生しました:
package test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestPostgresAutocommit {
public static void main(String[] args) throws Exception {
//System.out.println("start");
Connection connection= DriverManager.getConnection("jdbc:postgresql://pgdev/dbxxx","xxx","xxx");
connection.setAutoCommit(true);
Connection connection2= DriverManager.getConnection("jdbc:postgresql://pgdev/dbdxxx","xxx","xxx");
connection2.setAutoCommit(true);
Statement statement=connection.createStatement();
for (int i=0; i<10; i++) {
statement.execute("insert into test_gc(col1,col2) values ("+ i + "," + "'" + i + "')");
}
statement.close();
countElements(connection2);
statement=connection.createStatement();
statement.execute("delete from test_gc");
statement.close();
statement=connection.createStatement();
statement.execute("begin");
for (int i=0; i<10; i++) {
statement.execute("insert into test_gc(col1,col2) values ("+ i + "," + "'" + i + "')");
}
connection.rollback();
countElements(connection2);
}
private static void countElements(Connection connection2) throws Exception {
Statement statement2=connection2.createStatement();
ResultSet rs=statement2.executeQuery("select count(*) from test_gc");
rs.next();
System.out.println("row num in table=" + rs.getInt(1));
rs.close();
statement2.close();
}
}