JDBC事务中,我明明只捕获了Exception,为什么当出现Error时也能保证数据正确呢?
我学习的内容:Java + JDBC + MySQL
代码逻辑很简单:捕获了SQLException:如果出现SQLException就回滚。
但是我发现,即使出现了我没有声明要捕获的ArithmeticException和StackOverflowError,数据仍然没有变化。
就好像是捕获到了我未声明的异常,然后自动回滚了一样。
即使我不用PrepareStatement,而用Statement也是一样的结果。
去看过源码了,也打了断点调试了半天,被淹死在源码里了…
请问这是什么原理呢?
菜鸟一只,恳请大佬赐教。
感谢!
代码如下:
public class Demo06_Transaction {
public static void main(String[] args) {
String sql_zhangsan = "UPDATE tb01_jdbc SET balance=balance+? WHERE name=?";
String sql_lisi = "UPDATE tb01_jdbc SET balance=balance-? WHERE name=?";
Connection conn = null;
PreparedStatement pstmt_zhangsan = null;
PreparedStatement pstmt_lisi = null;
try {
conn = JDBCUtils.getConn();
// 开启事务
conn.setAutoCommit(false); // 这里逻辑是不设置为自动提交,即手动开启了事务
// zhangsan增加200
pstmt_zhangsan = conn.prepareStatement(sql_zhangsan);
pstmt_zhangsan.setInt(1, 200);
pstmt_zhangsan.setString(2, "zhangsan");
pstmt_zhangsan.executeUpdate();
System.out.println("张三账户里增加了200");
// 在此处制造ArithmeticException
int i = 1 / 0;
// 在此处制造Error,仍然能够保证数据正确 zz 原因不知道
methodA(); // Exception in thread "main" java.lang.StackOverflowError
// lisi减少200
pstmt_lisi = conn.prepareStatement(sql_lisi);
pstmt_lisi.setInt(1, 200);
pstmt_lisi.setString(2, "lisi");
pstmt_lisi.executeUpdate();
System.out.println("李四账户里减少了200");
// 提交事务
conn.commit();
} catch (SQLException e) { //
e.printStackTrace();
// 出现异常,回滚事务
try {
if (conn != null) {
conn.rollback();
System.out.println("数据已回滚"); // 出现了未声明要获取的StackOverflowError、ArithmeticException时确实没有运行
}
} catch (SQLException ex) {
ex.printStackTrace();
}
} finally {
JDBCUtils.close(pstmt_zhangsan, conn);
JDBCUtils.close(pstmt_lisi, conn);
}
}
// 无限递归制造Error
private static void methodA() {
methodA(); // Exception in thread "main" java.lang.StackOverflowError
}
}
你好,
首先你要知道事务只有提交了才能真正的更新到数据库中