Endelig opdatering :ja du kan ændre autoCommit flere gange, du kan også omgå det ved at bruge kommandoen commit/rollback i en sætning, som du opdagede. Mit råd er at holde fast i autoCommit indstillet til falsk og altid bruge transaktioner, hvor du har brug for dem.
Jeg bruger også Postgres og Oracle, og jeg bruger altid autocommit =falsk, da jeg ikke kan administrere transaktioner med autocommit =sand
Du kan ændre autocommit, som du testede, men jeg opfordrer dig til eksplicit at administrere transaktioner, selvom det er en enkelt erklæring.
Hvis du kan bruge en ramme som Spring (eller Guice), er der transaktionsstyring foretaget via AOP, og du behøver ikke besvære dig med commit og rollback instruktioner.
I Oracle afhænger bindingstiden ikke af mængden af begået data, og commit med en højere frekvens (med hensyn til funktionelle krav) kan også skade ydeevnen.
Opdater :Fra din kommentar anfører du, at Postgres respekterer transaktionsgrænser i autocommit; Jeg kan ikke gengive adfærden her er en simpel testcase:
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();
}
}
programmet kan ikke rulle tilbage med en undtagelse:
Så det er ikke muligt at administrere transaktioner, når autoCommit er sandt; fandt du noget andet?
Opdatering II :Selv med denne kode, som jeg tror, den afspejler dataene i din kommentar, fik jeg undtagelsen:
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();
}
}