java - 我可以多次更改 JDBC 连接的 AutoCommit 属性吗

标签 java oracle postgresql jdbc

我正在处理一个仅使用“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/

相关文章:

java - Hibernate 中的未知实体

java - mvn clean install 后修改了目标文件夹中的 .wav 文件,无法正常播放

java - Apache OpenNLP 词性标注器 : Trained on which data set?

sql - WITH子句和子查询的区别?

mysql - sql 脚本返回的值应用作下一个脚本的输入

oracle - ORA-01799 : a column may not be outer-joined to a subquery

php - 在 PostgreSQL 中用单引号插入值

mysql - 我如何检查我的 Db.Query 是否返回空行

postgresql - pgAdmin 到 pgpool 的连接错误

java - 断言列表中的属性