在JDBC中,autocommit为false并且没有设置显式保存点时,回滚是好风格还是浪费? [英] In JDBC, when autocommit is false and no explicit savepoints have been set, is it good style or a waste to rollback?

查看:12
本文介绍了在JDBC中,autocommit为false并且没有设置显式保存点时,回滚是好风格还是浪费?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您有以下代码:

Connection conn;
try
{
   conn = ... // get connection
   conn.setAutoCommit(false);

   ... // Do some modification queries and logic

   conn.commit()
} catch(SQLException e)
{
    conn.rollback() // Do we need this?
    conn.close()
}

在这段代码中,如果出现异常,是关闭连接(因为自动提交已关闭)还是显式回滚然后关闭连接更好?没有保存点.

In this code, if there is an exception, is it better style to just close the connection (since autocommit is off), or to explicitly roll back and then close the connection? There are no save points.

我觉得添加回滚调用可能有意义,因为:

I feel that it might make sense to add the rollback call because:

1) 将来有人可能会添加保存点但忘记添加回滚

1) Someone, in the future, might add save points but forget to add the rollback

2) 提高可读性

3) 它不应该花费任何东西,对吧?

3) It shouldn't cost anything, right ?

但显然,这些都不是特别引人注目.任何标准做法?

But obviously, none of these is particularly compelling. Any standard practice?

注意:我知道需要在关闭和回滚时重复尝试/捕获.我实际上有一个中间件来抽象数据库访问并处理它,但我想知道添加它是否是多余的.

Note: I'm aware of the need to do a repeat try/catch on closing and rollback. I actually have a middleware that abstracts the database access and takes care of that, but I was wondering whether adding it was superfluous.

推荐答案

正常的成语如下:

public void executeSomeQuery() throws SQLException {
    try (Connection connection = dataSource.getConnection()) {
        connection.setAutoCommit(false);

        try (PreparedStatement statement = connection.prepareStatement(SOME_SQL)) {
            // Fire transactional queries here.

            connection.commit();
        } catch (SQLException e) {
            connection.rollback();
            throw e;
        }
    }
}

请注意 Java 7 的 try-with-resources 声明try 块完成时,总是隐式调用资源上的 close(),就好像它发生在 finally 中一样.

Note that Java 7's try-with-resources statement always implicitly calls close() on the resource when the try block finishes, as if it happens in finally.

调用rollback()也是强制性的.即,它将重置连接的事务状态.池连接的 close() 不会这样做,只有 commit()rollback() 会这样做.不调用 rollback() 可能会导致池连接的下一个租约在其内存中仍然有前一个事务的(成功)查询.

Calling rollback() is also mandatory when it concerns a pooled connection. Namely, it will reset the transactional state of the connection. The close() of a pooled connection won't do that, only the commit() and rollback() will do that. Not calling rollback() may lead that the next lease of the pooled connection will still have the (successful) queries of the previous transaction in its memory.

另见Connection#close()(重点不是我的):

See also javadoc of Connection#close() (emphasis not mine):

强烈建议应用程序在调用 close 方法之前明确提交或回滚活动事务.如果 close 方法被调用并且有一个活动的事务,结果是实现定义的.

It is strongly recommended that an application explicitly commits or rolls back an active transaction prior to calling the close method. If the close method is called and there is an active transaction, the results are implementation-defined.

这篇关于在JDBC中,autocommit为false并且没有设置显式保存点时,回滚是好风格还是浪费?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆