我正在处理一个仅使用“autoCommit=true”创建连接的连接池。
但是,对于我的特定用例,我需要“autoCommit=false”以便我可以在 JDBC 语句上设置“获取大小”属性。
我的初始测试表明我可以在 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,您也可以在您发现的语句中使用提交/回滚命令来解决它。我的建议是坚持将 autoCommit 设置为 false,并始终在需要时使用事务。
我也在使用 Postgres 和 Oracle,并且我总是使用 autocommit = false,因为我无法使用 autocommit = true 来管理事务
您可以在测试时更改自动提交,但我鼓励您显式管理事务,即使它是单个语句。
如果您可以使用像 Spring(或 Guice)这样的框架,则可以通过 AOP 进行事务管理,并且您不需要为提交和回滚指令而烦恼。
在 Oracle 中,提交时间不取决于提交的数据量,并且更高频率的提交(相对于功能需求)也会损害性能。
更新:根据您的评论,您声明 Postgres 尊重自动提交中的事务边界;我无法重现这里的行为是一个简单的测试用例:
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: Cannot rollback when autoCommit is enabled.
所以当 autoCommit 为真时,无法管理事务;有没有发现不一样的地方?
更新 II:即使我认为这段代码反射(reflect)了您评论中的数据,我也得到了异常:
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/