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 classTransactionTest {public static intupdate(Connection con,String sql,Object...args) {
PreparedStatement ps= null;try{
ps=con.prepareStatement(sql);for(int i=0;i
ps.setObject(i+1, args[i]);returnps.executeUpdate();
}catch(Exception ex) {
ex.printStackTrace();
}finally{
JDBCUtils.closeResource(null, ps);
}return 0;
}//要保证几个DML操作作为一个整体出现,要么都做,要么都不做
public static voidtestUpdateWithTx() {
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 voidmain(String []args) {
testUpdateWithTx();
}
}