JDBC回滚方法的行为与预期不符

时间:2014-07-17 13:29:43

标签: java mysql sql jdbc rollback

我正在用MySQL数据库中的Java处理数据开发一个软件,由于回滚调用没有做我期望的事情,我面临一个问题...我的函数由两个查询组成,我需要回滚如果第二个查询未执行(或有错误),以保持一致的数据。这是我的代码,我一直在做一个语法错误,故意在第二次查询执行期间抛出错误。调用rollback方法,但我的第一个语句在我的数据库中执行并提交,你能解释一下为什么吗?

    @Override
    public void updateIndicatorRemainingTimeAndExecuted(int id) throws ServiceException {
        PreparedStatement stmt = null;
        Connection con = null;
        String query1 = "UPDATE "+indicatorSchedulerTable+" i " 
        +"JOIN adv_frequency f ON i.id_frequency = f.id_frequency "
        +"SET i.ind_remainingtime = i.ind_remainingtime + f.frq_seconds WHERE id_indicator = ?";
        String query2 = "UPDATE "+indicatorSchedulerTable
                +" SET ind_executing =  WHERE id_indicator = ?";
        try {
            con = mySQLManipulator.getConnection();
            stmt = con.prepareStatement(query1);
            stmt.setInt(1,id);
            /*Updating remaining time*/
            stmt.executeUpdate();
            stmt.close();
            /*Updating executing status*/
            stmt = con.prepareStatement(query2);
            stmt.setInt(1,id);
            stmt.executeUpdate();
            con.commit();
        } catch (SQLException e) {
            try {
                con.rollback();
                System.out.println("ROLLBACK OK");
            } catch (SQLException e1) {
                throw new ServiceException("Problème de rollback lors de la mise à jour dans la fonction \"updateIndicatorRemainingTimeAndExecuted\" : "+e1.getMessage()+e.getMessage());
            }
            throw new ServiceException("Problème lors de la mise à jour dans la fonction \"updateIndicatorRemainingTimeAndExecuted\" : "+e.getMessage());
        } finally {
            handleDatabaseClosure(con, stmt, null);
        }
    }

我也在使用像这样的连接池,可能是因为这个错误:

public class JDBCManipulator {
    private static final BasicDataSource dataSource = new BasicDataSource();
    private DBType type = null;
    private String URI = null;

    public JDBCManipulator(DBType type, String URI, String user, String password) throws Exception {
        if(type == DBType.PHOENIX){
            Class.forName("org.apache.phoenix.jdbc.PhoenixDriver");
        } else if(type == DBType.MYSQL) {
            dataSource.setDriverClassName("com.mysql.jdbc.Driver");
            dataSource.setUrl(URI);
            dataSource.setUsername(user);
            dataSource.setPassword(password);
            dataSource.setMaxActive(20);
            dataSource.setDefaultAutoCommit(false);
        } else {
            throw new Exception("Le type fournit ("+type+") pour l'initialisation de JDBCManipulator n'est pas connu ...");
        }
        this.type = type;
        this.URI = URI;
    }

    public Connection getConnection() throws SQLException {
        Connection conn = null;
        if(type == DBType.MYSQL){
            conn = dataSource.getConnection();
        } else {
            conn = DriverManager.getConnection(URI);    
        }
        return conn;
    }
}

2 个答案:

答案 0 :(得分:0)

您必须将连接的autoCommit设置为false。

con.setAutoCommit(false);

否则,每个执行的更新都将立即提交。

此外,使用支持InnoDB等交易的存储引擎。 MyISAM不支持交易。

答案 1 :(得分:0)

我能够通过在CREATE语句中用ENGINE=MyISAM替换ENGINE=INNODB来使一切正常。谢谢大家的帮助!