我处理的连接池只创建“autoCommit=true”的连接。
但是,对于我的特定用例,我需要“autoCommit=false”,以便可以在JDBC语句上设置“fetch size”属性。
我的初始测试表明,我可以在JDBC连接实例上设置AutoCommit属性,然后在将连接返回池之前再次重置它。
Connection conn = pool.getConnection();
try {
conn.setAutoCommit(false);
// execute queries for my use case using above connection.
} finally {
conn.setAutoCommit(true);
// do other cleanup like statement and result set close
}
pool.returnConnection(conn);
有人知道这是不是一个正确的用例吗?
我正在使用Postgres,但以后可能会迁移到Oracle。
最佳答案
最终更新:是的,您可以多次更改autoCommit,您还可以在发现的语句中使用commit/rollback命令来解决它。我的建议是坚持将autoCommit设置为false,并始终在需要时使用事务。
我也在使用Postgres和Oracle,而且我总是使用autocommit=false,因为autocommit=true时我无法管理事务
您可以在测试时更改autocommit,但我建议您显式地管理事务,即使它是一条语句。
如果您可以使用像Spring(或Guice)这样的框架,那么就可以通过AOP进行事务管理,而不需要麻烦提交和回滚指令。
在Oracle中,提交时间不取决于提交的数据量,而且提交频率越高(就功能需求而言)也会影响性能。
更新:根据您的评论,您声明Postgres尊重autocommit中的事务边界;我无法重现以下行为:一个简单的测试用例:
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();
}
}
程序无法回滚,出现异常:
org.postgresql.util.PSQLException:当autoCommit为
启用。
因此,当autoCommit为true时,不可能管理事务;是否发现了不同的内容?
更新二:即使有这段代码,我认为它反映了你评论中的数据,但我还是得到了一个例外:
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();
}
}
关于java - 我可以多次更改JDBC连接的AutoCommit属性吗,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31321196/