在conn.commit()之后需要setautocommit(true)

时间:2012-09-13 08:31:54

标签: oracle jdbc

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

假设该连接上的autocommit为TRUE。

现在conn.setautocommit(false)已设定;

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

现在我需要明确地将代码setautocommit(true)恢复到之前的conn状态吗?

commit()\rollback()本身会设置setautocommit(true)吗?

3 个答案:

答案 0 :(得分:9)

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

如果从数据源获取它,则应将状态恢复到状态,因为数据源可能会将连接保留在池中,而下一段代码可能不会指望您集。

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

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

答案 1 :(得分:0)

conn.setAutoCommit(自动提交);应该转到finally块

答案 2 :(得分:0)

有趣的是,conn.setAutoCommit(true);意味着提交(如果它处于autoCommit(false)模式,请参阅here,但如果您仍然将其分解,那么人们可能会更清楚。