自定義事務註解
註解類
// 事務註解 設置傳播行爲 @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);
|