Ostateczna aktualizacja :tak, możesz zmienić autoCommit wiele razy, możesz również obejść to za pomocą polecenia commit/rollback w oświadczeniu, jak odkryłeś. Radzę trzymać się autoCommit ustawionego na false i zawsze używać transakcji tam, gdzie ich potrzebujesz.
Używam również Postgres i Oracle i zawsze używam autocommit =false, ponieważ nie mogę zarządzać transakcjami z autocommit =true
Możesz zmienić autocommit podczas testowania, ale zachęcam do jawnego zarządzania transakcjami, nawet jeśli jest to pojedyncza instrukcja.
Jeśli możesz użyć frameworka takiego jak Spring (lub Guice), zarządzanie transakcjami odbywa się za pośrednictwem AOP i nie musisz zawracać sobie głowy instrukcjami zatwierdzania i cofania zmian.
W Oracle czas zatwierdzania nie zależy od ilości danych, a zatwierdzanie z większą częstotliwością (w odniesieniu do wymagań funkcjonalnych) może również obniżyć wydajność.
Aktualizacja :W swoim komentarzu stwierdzasz, że Postgres przestrzega granic transakcji w autocommit; Nie mogę odtworzyć tego zachowania, to prosty przypadek testowy:
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();
}
}
program nie wycofuje się z wyjątkiem:
Dlatego nie jest możliwe zarządzanie transakcjami, gdy autoCommit jest prawdziwe; czy znalazłeś coś innego?
Aktualizacja II :Nawet z tym kodem, który moim zdaniem odzwierciedla dane w twoim komentarzu, mam wyjątek:
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();
}
}