package com.itheima.util; import java.sql.Connection; import java.sql.SQLException; //封装了所有与事务有关的方法 public class TransactionManager { private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>(); public static Connection getConnection(){ Connection conn = tl.get(); if(conn==null){//从当前线程中获取链接 conn = DBCPUtil.getConnection(); tl.set(conn); } return conn; } public static void startTransaction(){ try { Connection conn = getConnection(); conn.setAutoCommit(false); } catch (SQLException e) { e.printStackTrace(); } } public static void rollback(){ try { Connection conn = getConnection(); conn.rollback(); } catch (SQLException e) { e.printStackTrace(); } } public static void commit(){ try { Connection conn = getConnection(); conn.commit(); } catch (SQLException e) { e.printStackTrace(); } } public static void release(){ try { Connection conn = getConnection(); conn.close(); tl.remove();//从当前线程中解绑。 与服务器实现有关:服务器采用线程池。 } catch (SQLException e) { e.printStackTrace(); } } }
package com.itheima.util; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import com.itheima.service.BusinessService; import com.itheima.service.impl.BusinessServiceImpl; //AOP public class BeanFactory { public static BusinessService getBusinessService(){ final BusinessService s = new BusinessServiceImpl(); BusinessService proxyS = (BusinessService)Proxy.newProxyInstance(s.getClass().getClassLoader(), s.getClass().getInterfaces(), new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { TransactionManager.startTransaction(); Object rtValue = method.invoke(s, args); return rtValue; } catch (Exception e) { TransactionManager.rollback(); throw new RuntimeException(e); } finally { TransactionManager.commit(); TransactionManager.release(); } } }); return proxyS; } }
package com.itheima.service; public interface BusinessService { /** * 转账 * @param sourceAccountName 转出账户 * @param targetAccontName 转入账户 * @param money 交易金额 */ void transfer(String sourceAccountName,String targetAccontName,float money); }
package com.itheima.service.impl; import com.itheima.dao.AccountDao; import com.itheima.dao.impl.AccountDaoImpl; import com.itheima.domain.Account; import com.itheima.service.BusinessService; //业务层控制事务 public class BusinessServiceImpl implements BusinessService { private AccountDao dao = new AccountDaoImpl(); public void transfer(String sourceAccountName, String targetAccontName, float money) { Account sAccount = dao.findByName(sourceAccountName); Account tAccount = dao.findByName(targetAccontName); sAccount.setMoney(sAccount.getMoney() - money); tAccount.setMoney(tAccount.getMoney() + money); dao.updateAcount(sAccount); // int i=1/0; dao.updateAcount(tAccount); } }
package com.itheima.view; import com.itheima.service.BusinessService; import com.itheima.service.impl.BusinessServiceImpl; import com.itheima.util.BeanFactory; public class Client { public static void main(String[] args) { BusinessService s = BeanFactory.getBusinessService(); s.transfer("aaa", "bbb", 100); } }