Bản cập nhật cuối cùng :vâng, bạn có thể thay đổi autoCommit nhiều lần, bạn cũng có thể giải quyết nó bằng cách sử dụng lệnh commit / rollback trong một câu lệnh mà bạn đã phát hiện ra. Lời khuyên của tôi là gắn với autoCommit được đặt thành false và luôn sử dụng các giao dịch khi bạn cần.
Tôi cũng đang sử dụng Postgres và Oracle và tôi luôn sử dụng autocommit =false, vì tôi không thể quản lý các giao dịch bằng autocommit =true
Bạn có thể thay đổi tự động gửi khi bạn đã thử nghiệm nhưng tôi khuyến khích bạn quản lý các giao dịch một cách rõ ràng ngay cả khi đó là một câu lệnh duy nhất.
Nếu bạn có thể sử dụng một khuôn khổ như Spring (hoặc Guice) thì có quản lý giao dịch được thực hiện thông qua AOP và bạn không cần bận tâm đến các hướng dẫn cam kết và khôi phục.
Trong Oracle, thời gian cam kết không phụ thuộc vào lượng dữ liệu được cam kết và việc cam kết với tần suất cao hơn (đối với các yêu cầu chức năng) cũng có thể ảnh hưởng đến hiệu suất.
Cập nhật :Từ nhận xét của bạn, bạn tuyên bố rằng Postgres tôn trọng các ranh giới giao dịch trong tự động gửi; Tôi không thể tái tạo hành vi ở đây là một trường hợp thử nghiệm đơn giản:
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();
}
}
chương trình không thể khôi phục với một Ngoại lệ:
Vì vậy, không thể quản lý các giao dịch khi AutoCommit là true; bạn có thấy điều gì khác biệt không?
Cập nhật II :Ngay cả với mã này mà tôi nghĩ rằng nó phản ánh dữ liệu trong nhận xét của bạn, tôi vẫn nhận được Ngoại lệ:
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();
}
}