在WEB的三層架構的業務邏輯層中,每一個業務邏輯方法,要麼執行成功,提交事務;要麼執行失敗,回滾事務。數據庫
下面用代理的方式實現事務的控制:架構
封裝了兩個工具類DBUtil
, TranscationUtil
, 前者用於當前線程的數據庫鏈接的獲取和關閉,後者控制當前線程數據庫鏈接事務的處理。ide
首先,新建動態代理類com.ploy.service.proxy.TranscationProxy
類,並使用cglib實現動態代理:工具
/** * 數據庫事務代理類 * * @author * */ public class TranscationProxy { /** * 得到代理對象 */ public static <T> T getProxy(Class<T> clazz) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(clazz); // 設置回調方法 enhancer.setCallback(new MethodInterceptor() { /* * 事務方法攔截 * @param object 被代理的對象(service對象) * @param method 被調用的方法(原service的某個方) * @param args 被代理的方法的傳入參數 * @param proxy 多出來的參數是MethodProxy 類型的,它應該是cglib生成用來代替Method對象的一個對象 */ @Override public Object intercept(Object object, Method method, Object[] args, MethodProxy proxy) throws Throwable { Object result = null; // 開啓一個全新的事務 TranscationUtil.begin(); try { result = proxy.invokeSuper(object, args); // 反射執行原有serivce方法 // 執行成功,提交事務 TranscationUtil.commit(); } catch (Exception e) { // 執行失敗回滾事務 TranscationUtil.rollback(); throw e; } } }); // 建立一個代理對象 return (T) enhancer.create(); } }
而後看看Service工廠類,實際上生產的是具備代理功能的Serice對象:線程
/** * ServiceFactory類工廠 * * @author * */ public class ServiceFactory { private static Map<Class<?>, Object> SERVICE_MAP = new HashMap<>(); static { SERVICE_MAP.put(ManagerService.class, TranscationProxy.getProxy(ManagerServiceImpl.class)); SERVICE_MAP.put(UserService.class, TranscationProxy.getProxy(UserServiceImpl.class)); } public static<T> T getService(Class<T> clazz) { return (T) SERVICE_MAP.get(clazz); } }
經過工廠類向控制層注入帶有事務功能的service對象。代理