package cn.taylor.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
/*
* 学习事务最简单的例子就是转账,假如张三给李四转100块钱,其实用两句sql语句就可以实现,
* 第一句是给张三账户减去100;第二句是给李四账户加上100
* 但是如果在第一句sql语句执行之后出现错误,导致第二句没有执行,就会出现张三的钱少了,
* 而李四的钱没加,为了避免这种情况,我们学习事务。
* 一旦拥有了事务的原子性,事务中的操作要么全部执行,要么全部执行失败。
*/
/*
* jdbc中的事务的代码格式
* try{
* con.setAutoCommit(false); //开启事务
* ...
* ....
* con.commit(); //try的最后提交事务
* }
* catch(){
* con.rollback(); //回滚事务,表示结束
* }
*/
public class AccountDao {
/*
* 修改时指定用户的余额
*/
public void updateBalance(Connection con,String name,double balance){
try{
//在jdbc中处理事务,都是通过Connection对象完成的。
/*
* 在同一事务中所有的操作,都在使用同一个Connection对象,为了保证这一点 ,
* 所以要将下面代码修改。
* 改成是在方法的参数中提供Connection对象
*/
//Connection con =JdbcUtils.getConnection();
String sql="update balance set balance=balance+? where name=?";
PreparedStatement pstmt=con.prepareStatement(sql);
pstmt.setDouble(1, balance);
pstmt.setString(2, name);
pstmt.executeUpdate();
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
package cn.taylor.dao;
import java.sql.Connection;
import java.sql.SQLException;
import org.junit.Test;
/*
* 所有对Connection的操作都在Service层进行的处理
* 之后我们要改进这个问题,我们要把所有对Connection的操作隐藏起来,这需要使用
* 自定义的小工具。
*/
public class Demo1 {
public void zhuanzhang(String from,String to,double money) throws Exception{
//对事物的操作必须使用Connection对象
Connection con=null;
try{
con=JdbcUtils.getConnection();
con.setAutoCommit(false); //设置不要自动提交
AccountDao dao=new AccountDao();
dao.updateBalance(con, from, -money);
dao.updateBalance(con, to, money);
con.commit();
con.close();
}catch(Exception e){
try{
con.rollback();
con.close();
}catch(SQLException e1){}
throw new RuntimeException(e);
}
}
@Test
public void fun1() throws Exception{
zhuanzhang("zhangsan","lisi",100);
}
}