手寫Spring事務框架-註解版本

自定義事務註解

註解類

 

// 事務註解 設置傳播行爲

@Target({ ElementType.METHOD })

@Retention(RetentionPolicy.RUNTIME)

public @interface ExtTransaction {

 

}

 

事務工具類

//編程事務(需要手動begin 手動回滾  手都提交)

@Component()

@Scope("prototype") // 設置成原型解決線程安全

public class TransactionUtils {

 

      private TransactionStatus transactionStatus;

      // 獲取事務源

      @Autowired

      private DataSourceTransactionManager dataSourceTransactionManager;

 

      // 開啓事務

      public TransactionStatus begin() {

            transactionStatus = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());

            return transactionStatus;

      }

 

      // 提交事務

      public void commit(TransactionStatus transaction) {

            dataSourceTransactionManager.commit(transaction);

      }

 

      // 回滾事務

      public void rollback() {

            System.out.println("rollback");

            dataSourceTransactionManager.rollback(transactionStatus);

      }

 

}

}

 

切面類

@Aspect

@Component

public class AopExtTransaction {

@Autowired

      private TransactionUtils transactionUtils;

 

      @AfterThrowing("execution(* com.haha.service.*.*.*(..))")

      public void afterThrowing() throws NoSuchMethodException, SecurityException {

            // isRollback(proceedingJoinPoint);

            System.out.println("程序發生異常");

            // TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

            // TransactionStatus currentTransactionStatus =

            // TransactionAspectSupport.currentTransactionStatus();

            // System.out.println("currentTransactionStatus:" +

            // currentTransactionStatus);

            transactionUtils.rollback();

      }

 

      // // 環繞通知 在方法之前和之後處理事情

      @Around("execution(* com.haha.service.*.*.*(..))")

      public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

 

            // 調用方法之前執行

            TransactionStatus transactionStatus = begin(proceedingJoinPoint);

            proceedingJoinPoint.proceed();// 代理調用方法 注意點: 如果調用方法拋出異常不會執行後面代碼

            // 調用方法之後執行

            commit(transactionStatus);

      }

 

      public TransactionStatus begin(ProceedingJoinPoint pjp) throws NoSuchMethodException, SecurityException {

 

            // // 判斷是否有自定義事務註解

            ExtTransaction declaredAnnotation = getExtTransaction(pjp);

            if (declaredAnnotation == null) {

                  return null;

            }

            // 如果有自定義事務註解,開啓事務

            System.out.println("開啓事務");

            TransactionStatus transactionStatu = transactionUtils.begin();

            return transactionStatu;

      }

 

      public void commit(TransactionStatus transactionStatu) {

            if (transactionStatu != null) {

                  // 提交事務

                  System.out.println("提交事務");

                  transactionUtils.commit(transactionStatu);

            }

      }

 

      public ExtTransaction getExtTransaction(ProceedingJoinPoint pjp) throws NoSuchMethodException, SecurityException {

            // 獲取方法名稱

            String methodName = pjp.getSignature().getName();

            // 獲取目標對象

            Class<?> classTarget = pjp.getTarget().getClass();

            // 獲取目標對象類型

            Class<?>[] par = ((MethodSignature) pjp.getSignature()).getParameterTypes();

            // 獲取目標對象方法

            Method objMethod = classTarget.getMethod(methodName, par);

            // // 判斷是否有自定義事務註解

            ExtTransaction declaredAnnotation = objMethod.getDeclaredAnnotation(ExtTransaction.class);

            if (declaredAnnotation == null) {

                  System.out.println("您的方法上,沒有加入註解!");

                  return null;

            }

            return declaredAnnotation;

 

      }

 

      // 回滾事務

      public void isRollback(ProceedingJoinPoint pjp) throws NoSuchMethodException, SecurityException {

            // // 判斷是否有自定義事務註解

            ExtTransaction declaredAnnotation = getExtTransaction(pjp);

            if (declaredAnnotation != null) {

                  System.out.println("已經開始回滾事務");

                  // 獲取當前事務 直接回滾

                  TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

                  return;

            }

      }

 

測試

@ExtTransaction

public void add() {

userDao.add("test001", 20);

int i = 1 / 0;

System.out.println("################");

userDao.add("test002", 21);

 

 

發佈了365 篇原創文章 · 獲贊 23 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章