LocalThread的应用转入转出对事务的控制
因为我们要在服务层写转账的控制,而服务层和Dao层如何得到相同的Connection进行事务的控制是一个棘手的问题
ThreadLocal 线程局部变量,每个线程的变量是不可以互相访问,互不影响的。
主要有 get set remove方法
所以用到了ThreadLocal,用它来从数据源获取一个Connection ,写四个静态方法 ,
记得
static ThreadLocal<Connection> tl = new ThreadLocal<Connection>(); //注意第一次获取到是空的要 给从数据源中分配一个,以后直接返回即可 public static Connection getConnection() { if(tl.get() == null) { tl.set(C3P0Utils.getConnection()); } return tl.get(); }
//开始事务,不自动提交 public static void begin() { try { getConnection().setAutoCommit(false); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //事务确定执行完再提交 public static void commit() { try { getConnection().commit(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //事务出错,要回滚,所以这个方法一般写在catch中 public static void rollback() { try { getConnection().rollback(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //事务执行完,要关闭,在localThread中清除这个 public static void Close() { try { tl.get().close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } tl.remove(); }
用它来从数据源获取一个Connection , 再在 服务层和Dao层分别 用这个类的static方法获取这个Connection
这段代码体现了它对事务的控制
AcountDao ad = new AcountDaoImpl(); public void transfer(String fromName, String toName, Integer money) { // TODO Auto-generated method stub try { MyConnection.begin(); //获得转入和转出账户 Acounts fromAcount = ad.FindAcountByName(fromName); Acounts toAcount = ad.FindAcountByName(toName); //设置金额 fromAcount.setAcount(fromAcount.getAcount()-money); toAcount.setAcount(toAcount.getAcount()+money); //转入转出 ad.UpdateAcount(fromAcount); ad.UpdateAcount(toAcount); MyConnection.commit(); } catch (Exception e) { MyConnection.rollback(); // TODO Auto-generated catch block e.printStackTrace(); } finally { MyConnection.Close(); }