Poslední aktualizace :ano, autoCommit můžete změnit vícekrát, můžete to také obejít pomocí příkazu commit/rollback v příkazu, jak jste zjistili. Moje rada je držet se autoCommit nastaveného na false a vždy používat transakce tam, kde je potřebujete.
Také používám Postgres a Oracle a vždy používám autocommit =false, protože nemohu spravovat trasy s autocommit =true
Autocommit můžete změnit, jak jste testovali, ale doporučuji vám spravovat transakce explicitně, i když se jedná o jeden příkaz.
Pokud můžete použít framework jako Spring (nebo Guice), existuje správa transakcí přes AOP a nemusíte se obtěžovat s instrukcemi pro potvrzení a vrácení.
V Oracle doba odevzdání nezávisí na množství odevzdaných dat a zapisování s vyšší frekvencí (s ohledem na funkční požadavky) může také snížit výkon.
Aktualizovat :Z vašeho komentáře uvádíte, že Postgres respektuje transakční hranice v autocommit; Nemohu toto chování reprodukovat, je to jednoduchý testovací případ:
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();
}
}
programu se nepodaří vrátit zpět s výjimkou:
Není tedy možné spravovat transakce, když je autoCommit pravdivé; našli jste něco jiného?
Aktualizace II :I s tímto kódem, o kterém si myslím, že odráží data ve vašem komentáři, jsem dostal výjimku:
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();
}
}