Java 我可以多次更改JDBC连接的自动提交属性吗
我正在处理一个只创建“autoCommit=true”连接的连接池 但是,对于我的特定用例,我需要“autoCommit=false”,以便可以在JDBC语句上设置“fetch size”属性 我的初始测试表明,我可以在JDBC连接实例上设置AutoCommit属性,然后在将连接返回到池之前再次重置它Java 我可以多次更改JDBC连接的自动提交属性吗,java,oracle,postgresql,jdbc,Java,Oracle,Postgresql,Jdbc,我正在处理一个只创建“autoCommit=true”连接的连接池 但是,对于我的特定用例,我需要“autoCommit=false”,以便可以在JDBC语句上设置“fetch size”属性 我的初始测试表明,我可以在JDBC连接实例上设置AutoCommit属性,然后在将连接返回到池之前再次重置它 Connection conn = pool.getConnection(); try { conn.setAutoCommit(false); // execute querie
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。最终更新:是的,您可以多次更改自动提交,也可以在发现时在语句中使用commit/rollback命令解决此问题。我的建议是坚持将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();
}
}
封装测试;
导入java.sql.Connection;
导入java.sql.DriverManager;
导入java.sql.ResultSet;
导入java.sql.SQLException;
导入java.sql.Statement;
公共类TestPostgresAutocommit{
公共静态void main(字符串[]args)引发异常{
Connection Connection=DriverManager.getConnection(“jdbc:postgresql://pgdev/dbxxx“,”xxx“,”xxx“);
connection.setAutoCommit(true);
connection2=DriverManager.getConnection(“jdbc:postgresql://pgdev/dbxxx“,”xxx“,”xxx“);
连接2.设置自动提交(真);
语句Statement=connection.createStatement();
对于(int i=0;i不幸的是,这里既不能使用Spring也不能使用任何其他框架。我在测试中发现,即使autoCommit=true,postgres在设置事务边界时也会尊重事务边界。这不是你的经验吗?还是oracle测试。@Mecon这不是我的经验,我用在main方法中,在第二个for循环之前,创建一个全新的语句。在此语句中,“begin”不是问题。如果“begin”如果已发出,则将设置显式事务边界语句,这将允许postgres回滚。请确认吗?如果我在begin命令(close+create语句)后提交两行结果是一样的,除了不确定你的意思,但让我详细说明一下:这是我认为我们在第二个“for循环”之前需要的一行:statement.execute(“begin”);如果你在第二个“for循环”之前添加这一行,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 {
//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();
}
}