package transaction; import jdbc.utils.*; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; /* * 1.一个事物里的操作要么都执行,要么都不执行 * 事物:一个或多个DML操作 * 2.事物处理原则:所有操作都完成时被commit,使修改永久保存 * 反之放弃所有操作,事物rollback到最初状态 * 3.提交后就不可回滚 * 4.DDL一旦执行,就会自动提交 * 5.DML默认自动提交,但是可以set autocommit = false 进行设置 * 6.默认在关闭连接时会自动提交数据 * */ public class TransactionTest { public static int update(Connection con,String sql,Object...args) { PreparedStatement ps = null; try { ps=con.prepareStatement(sql); for(int i=0;i<args.length;i++) ps.setObject(i+1, args[i]); return ps.executeUpdate(); } catch(Exception ex) { ex.printStackTrace(); } finally { JDBCUtils.closeResource(null, ps); } return 0; } //要保证几个DML操作作为一个整体出现,要么都做,要么都不做 public static void testUpdateWithTx() { Connection con = null; try { con = JDBCUtils.getConnection(); System.out.println(con.getAutoCommit()); //取消数据的自动提交来对应中间的异常 con.setAutoCommit(false); String sql = "update blank set money = money-100 where blankId = ?"; update(con,sql,0); //System.out.println(10/0);//模拟网络异常 sql = "update blank set money = money+100 where blankId = ?"; update(con,sql,1); System.out.println("转账成功"); con.commit(); } catch(Exception ex) {//出现异常就必须rollback ex.printStackTrace(); try { con.rollback(); } catch (SQLException e) { e.printStackTrace(); } } finally { try {//最后要把这个连接进行还原,再返回到数据库的连接池里去 con.setAutoCommit(true); } catch(SQLException e) { e.printStackTrace(); } JDBCUtils.closeResource(con, null); } } public static void main(String []args) { testUpdateWithTx(); } }
1