java - JDBC 回滚方法的行为与预期不同

标签 java mysql sql jdbc rollback

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

    @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;
    }
}

最佳答案

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

con.setAutoCommit(false);

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

另外,使用像InnoDB这样支持事务的存储引擎。 MyISAM 不支持事务。

关于java - JDBC 回滚方法的行为与预期不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24804952/

相关文章:

java - Netbeans GUI 将文本字段值传递给应用程序中而不是 View 中定义的操作

java - 无效的 ADTS sampling_frequency_index 和 channel_configuration 为什么?

java - 在 if 语句中使用 boolean 方法时遇到问题

java - 将变量从一个 POJO 复制到另一个

PHP日期时间转换保存到MySQL

mysql - 将隐藏文件输入的值插入数据库?

日期时间类型的 SQL LIKE 语句

mysql 关注和转推功能

mysql - Docker:在停止的容器中编辑 "my.cnf"文件

java - 在sql语句中使用java变量