当前位置: 首页 > 知识库问答 >
问题:

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

顾英发
2023-03-14

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

共有1个答案

谯德佑
2023-03-14

最终更新:是的,您可以多次更改自动提交,还可以在发现时在语句中使用提交/回滚命令来解决此问题。我的建议是坚持将autoCommit设置为false,并始终在需要时使用事务。

我也在使用Postgres和Oracle,我总是使用autocommit=false,因为我不能用autocommit=true来管理事务

您可以在测试时更改自动提交,但我鼓励您明确管理事务,即使它是一条语句。

如果您可以使用像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();

    }

}

程序无法通过异常回滚:

组织。postgresql。util。PSQLException:启用自动提交时无法回滚。

因此,当自动提交为真时,不可能管理事务;你有什么不同的发现吗?

更新二:即使有了这段代码,我认为它反映了你评论中的数据,我还是得到了一个例外:

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();

    }

}
 类似资料:
  • 问题内容: 是否可以“监视”指令上的ui更改?像这样的东西: 问题答案: 是。您可以使用,如果你在属性利用插值。 但是,如果这不是一个插值属性,并且您希望它可以从应用程序中的其他位置更改(绝对不建议这样做,请阅读Common Pitfalls ),那么函数可以返回: 无论如何,对您来说最好的方法可能是更改更改元素类的代码。它何时更改?

  • 问题内容: 如果您熟悉Bean验证框架,那么您将无法获得方法参数的名称。因此,如果对方法的第一个参数执行@NotNull约束,并且验证失败,则getPropertyPath将类似于“ arg1”。 我想创建自己的@NotNull版本,该版本可以采用例如@NamedNotNull(“ emailAddress”)的值。但是我不知道如何在验证器中覆盖#getPropertyPath?有什么办法做到这一

  • 问题内容: 我在Tomcat上确实有一个用Java编写的webapp,默认情况下所有连接都应为。现在,如果我确实仅在事务中运行SELECT语句。我仍然需要打电话吗?仅关闭连接就足够了吗? 物有所值:我使用的是Oracle 11.2。 问题答案: 关闭连接就足够了,无需调用或。 但是根据connection.close(),建议调用commit或rollback。

  • 问题内容: 可以说我有一个具有两列和String数据类型的表。通常我写我的hql查询像 我可以编写将两个属性都连接在一起的hql查询吗? 也许像 问题答案: 或者,如果您想要分隔符: 请参阅文档。

  • 本文向大家介绍vue组件某个属性连续更改多次,会渲染几次,为什么?相关面试题,主要包含被问及vue组件某个属性连续更改多次,会渲染几次,为什么?时的应答技巧和注意事项,需要的朋友参考一下 vue组件某个属性连续更改多次,会渲染几次,为什么? 作者:zharthur

  • 问题内容: 我在HTML中创建了一个属性,该属性动态地填充了信息。 有没有一种方法可以检测属性值何时更改? 问题答案: 您将必须注意DOM节点的更改。有一个名为的API,但似乎对其的支持非常有限。这样的答案有一个指向API状态的链接,但是到目前为止,似乎在IE或Opera中都不支持它。 解决该问题的一种方法是让修改属性的代码部分分派一个您可以侦听的事件。 这里的代码是