16

conn从池中获取数据库连接 ( )。

假设autocommit在该连接上为 TRUE。

现在conn.setautocommit(false)已经设置;

然后经过几次声明更新,终于conn.commit()/conn.rollback()完成了。

现在我需要做明确的代码setautocommit(true)来恢复到以前的 conn 状态吗?

commit()\rollback()setautocommit(true)固有地设置?

4

3 回答 3

12

这取决于您从哪里获得该连接。如果您自己创建了连接,则无需恢复自动提交的状态。

如果您从数据源获得它,您应该将状态恢复到原来的状态,因为数据源可能会将连接保留在池中,并且下一段代码可能不会期望您设置的内容。

commit()不影响自动提交的值。启用自动提交只是确保 JDBC 驱动程序commit()在您执行的每个语句之后调用。你仍然可以随意调用commit(),只是不会有任何效果(除非它rollback()不会总是做你想做的事)。

[编辑]如何处理自动提交取决于您的连接池。dbcp有一个配置选项,可以在给您连接之前关闭自动提交,当您返回池时,c3p0将回滚连接。阅读有关您的连接池如何工作的文档。

如果您不知道使用了哪个池,安全的解决方案是在false获得连接时设置自动提交,并在遇到异常时回滚连接。我建议写一个包装器:

public <T> T withTransaction( TxCallback<T> closure ) throws Exception {
    Connection conn = getConnection();
    try {
        boolean autoCommit = conn.getAutoCommit();
        conn.setAutoCommit(false);

        T result = closure.call(conn); // Business code

        conn.commit();
        conn.setAutoCommit(autoCommit);
    } catch( Exception e ) {
        conn.rollback();
    } finally {
        conn.close();
    }
}

此代码将为您正确处理连接,您无需在业务代码中再担心它。

于 2012-09-13T08:34:27.170 回答
2

有趣的是,conn.setAutoCommit(true);暗示 a commit(如果它处于autoCommit(false)模式,请参阅此处,但如果您仍然将它们分开,人们可能会更清楚。

于 2018-05-07T21:49:14.253 回答
1

在 Oracle 12c 中,连接将默认为 autocommit true。但是如果将自动提交设置为false,则需要在释放到连接池之前将自动提交重置为true。conn.setAutoCommit(autoCommit); 应该移动到 finally 块

于 2017-04-04T09:59:41.213 回答