2 ming 2017 ming_2017 于 2017.01.15 23:57 提问

事务提交过程,出现异常,但是回滚事务失败,这是什么原因

/**
*实现事务:Tom 对Jerry 转账500元
*
*/
public class TransactionTest {

public static void update(Connection conn,String sql,Object ... args){
    PreparedStatement pstmt = null;
    try{
        pstmt = conn.prepareStatement(sql);//通过SQL语句 创建PreparedStatement 对象。

        //利用 for 循环对 SQL 语句中的 PreparedStatement 占位符 ,更新数据。
        for(int i = 0;i < args.length;i++){
            pstmt.setObject((i+1), args[i]);
        }
        //更新执行。
        pstmt.executeUpdate();

    }catch(Exception e){
        e.printStackTrace();
    }finally{
        //关闭数据库连接。
        JDBCTools.release(null, pstmt, null);
    }
}

public static void main(String[] args) {
    Connection conn = null;

    try{
        conn = JDBCTools.getConnection();

        //取消默认的提交方式
        conn.setAutoCommit(false);

        String sql = "UPDATE user SET balance = balance - 500 WHERE id = 2000001";
        update(conn, sql);

/*此处会 报com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException,Table 'ming.users' doesn't exist
但是,整个事务却没有回滚。*/

        sql = "UPDATE users SET balance = balance + 500 WHERE id = 2000002";
        update(conn,sql);

        //若事务操作正常,则提交事务
        conn.commit();

    } catch(Exception e){
        //若事务操作出现异常,则需要在异常处理中回滚事务
        try {
            conn.rollback();
        } catch (SQLException e1) {
            e1.printStackTrace();
        }
        e.printStackTrace();
    } finally{
        JDBCTools.release(null, null, conn);
    }
}

}

6个回答

sleeping_xixi
sleeping_xixi   2017.01.16 11:23
已采纳

我刚才写了一些代码,自己建了一个数据库表usertable,字段为id,name,进行了测试。
我先在你的代码中加入一些文字说明。好看出代码运行的地方。
图片说明
图片说明
更新成功的结果如下:
图片说明
更新失败的结果如下(当然,我是故意设置和你一样异常的结果,即找不到该数据库表):
图片说明
结果表明,无论成功或是失败,都执行了提交操作。
后来我将你的update方法注释掉,并将其具体代码放在了main方法中,如下图。
图片说明
结果就成功了。
图片说明
我猜想是你的update方法已经对该方法可能出现的异常做出了异常处理,所以对于Main函数的try就无法捕获异常,所以就认为是没有问题的,就一直这么执行下去了。
这个我也是想了挺久的,不知道有没有想对,但愿对你有帮助。

sleeping_xixi
sleeping_xixi 不客气。共同进步。
11 个月之前 回复
ming_2017
ming_2017 谢谢你了,应该是这个问题了,
11 个月之前 回复
ming_2017
ming_2017   2017.01.18 00:22
ming_2017
ming_2017   2017.01.18 00:23

图片说明

jinziweiwang
jinziweiwang   2017.01.16 09:28

报的语法错误,(user表能创建?)users表不存在,批量处理用addbatch()吧?这样才体现整体性

ming_2017
ming_2017 mysql中能创建的,users 我最初拼写错误,出了异常,但是事务提交了,没得到回滚。现在知道问题出在哪里了,谢谢你了
11 个月之前 回复
yh1276
yh1276   2017.01.16 09:29

可能第二个sql语句中表users不存在,没法回滚!

ming_2017
ming_2017 刚开始是拼写错误,但是后来想不对,出异常怎么事务还能提交,然后就发这个错误拼写的帖子,想找原因,现在找到了,谢谢你了
11 个月之前 回复
sleeping_xixi
sleeping_xixi   2017.01.16 15:29

如果对你有帮助,就回复我一声呗。我刚在这里回答问题不久,基本回答了就没有回应,所以不知道这样做有没有用。

ming_2017
ming_2017 回复奔跑的小猪: 嗯,我也是,弄明白,感觉理解也深一层了
11 个月之前 回复
sleeping_xixi
sleeping_xixi 其实为了想清楚这个问题,我花了三小时。那天早上睡醒看到了,也觉得好奇就试一试,结果弄到了接近中午。不过还是挺开心,也算把一个问题弄明白了。
11 个月之前 回复
ming_2017
ming_2017 想明白了,执行过程中,已经对异常进行了处理,在main方法中没有新的异常抛出来,自然不会被catch语句块捕获异常,自己居然就没有事务回滚了。
11 个月之前 回复
ming_2017
ming_2017 我截图出来了,就是这个原因,谢谢你了
11 个月之前 回复
ming_2017
ming_2017 我也很少看论坛,就是这个问题想了很久,没想明白,才尝试下发论坛找下答案
11 个月之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!