在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?

查看:374
本文介绍了在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语句总是隐式调用 尝试块结束时资源上的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.

另请参阅javadoc 连接#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天全站免登陆