Java MySQL事务和executeBatch

时间:2012-10-03 11:17:25

标签: java mysql transactions

我遇到了一个我无法弄清楚的问题。

我有以下SQL代码片段,其中我在表中插入多行。重要的是不要在异常上添加任何行。

代码按预期工作,但如果删除了回滚部分,则会在异常上添加一些行,即使connection.commit();永远不会被调用。那是为什么?

我担心的是:如果我的应用程序在调用批量插入时被操作系统杀死会发生什么,从而永远不会调用回滚部分。我的测试显示在这种情况下没有插入任何内容。但是,如果删除了回滚部分,我仍然偶然发现为什么会在异常中插入某些行。

有关此的任何提示吗?

    Connection connection = null;
    PreparedStatement stmt = null;

    try {
        connection = DBConnectionFactory.getInstance().getConnection(JDNI);
        connection.setAutoCommit(false);

        stmt = connection.prepareStatement(
                "INSERT INTO " + TABLE_PREFIX + TABLE_OUTBOX + "...");

        // add multiple statements

        stmt.executeBatch();

        connection.commit();

    } catch (Exception ex) {
        try {
            log.debug(ex);
            log.debug("rolling back insert message batch");
            connection.rollback();
            log.debug("rollback success");
        } catch(Exception e) {
            log.debug("unable to rollback", e);
        }
        throw new TranquilityException("could not insert endpoints!!", ex);
    } finally {
        if (stmt != null) {
            try {
                stmt.close();
            } catch (Exception ex) {
                log.warn("Could not close sql statement", ex);
            }
        }
        if (connection != null) {
            try {
                connection.setAutoCommit(true);
                connection.close();
            } catch (Exception ex) {
                log.error("Could not close sql connection", ex);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我可以看到有两个原因可以实现:

  • 首先,您似乎正在使用连接池。在这 case,您的连接被重用。如果您返回连接 池中未提交的事务,该连接由。签出 稍后的另一种方法是,事务可能会被提交 何时提交该方法。

  • 第二个(更有可能的)就是在你的终极块中,你是 设置connection.setAutoCommit(true);当您的方法完成时, 这将导致连接中的所有内容被刷新。我知道 您需要为连接池执行此操作,但您应该确保 在执行此操作之前,您的连接已处于已完成状态。