手动实现 spring 事务

    技术2025-10-15  9

    手动实现 spring 事务

    手动实现 spring 事务替换 @Transactional

    ## 自定义注解 @Target({ ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) public @interface ExtTransaction { }

    TransactionUtils

    // 编程事务(需要手动begin 手动回滚 手都提交) @Component @Scope("prototype") // 每个事务都是新的实例 目的解决线程安全问题 多例子 public class TransactionUtils { // 全局接受事务状态 private TransactionStatus transactionStatus; // 获取事务源 @Autowired private DataSourceTransactionManager dataSourceTransactionManager; // 开启事务 public TransactionStatus begin() { System.out.println("开启事务"); transactionStatus = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute()); return transactionStatus; } // 提交事务 public void commit(TransactionStatus transaction) { System.out.println("提交事务"); dataSourceTransactionManager.commit(transaction); } // 回滚事务 public void rollback() { System.out.println("回滚事务..."); dataSourceTransactionManager.rollback(transactionStatus); } }

    aop 实现

    // 自定义事务注解具体实现 @Aspect @Component public class AopExtTransaction { // 一个事务实例子 针对一个事务 @Autowired private TransactionUtils transactionUtils; // 使用异常通知进行 回滚事务 @AfterThrowing("execution(* com.itat.service.*.*.*(..))") public void afterThrowing() { // 获取当前事务进行回滚 // TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); transactionUtils.rollback(); } // 环绕通知 在方法之前和之后处理事情 @Around("execution(* com.itat.service.*.*.*(..))") public void around(ProceedingJoinPoint pjp) throws Throwable { // 1.获取该方法上是否加上注解 ExtTransaction extTransaction = getMethodExtTransaction(pjp); TransactionStatus transactionStatus = begin(extTransaction); // 2.调用目标代理对象方法 pjp.proceed(); // 3.判断该方法上是否就上注解 commit(transactionStatus); } private TransactionStatus begin(ExtTransaction extTransaction) { if (extTransaction == null) { return null; } // 2.如果存在事务注解,开启事务 return transactionUtils.begin(); } private void commit(TransactionStatus transactionStatus) { if (transactionStatus != null) { // 5.如果存在注解,提交事务 transactionUtils.commit(transactionStatus); } } // 获取方法上是否存在事务注解 private ExtTransaction getMethodExtTransaction(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 extTransaction = objMethod.getDeclaredAnnotation(ExtTransaction.class); return extTransaction; } }

    调用过程

    // @ExtTransaction @Transactional public void add() { // 调用接口的时候 接口失败 需要回滚,但是日志记录不需要回滚。 logService.addLog(); // 后面程序发生错误,不能影响到我的回滚### 正常当addLog方法执行完毕,就应该提交事务 userDao.add("test001", 20); // int i = 1 / 0; System.out.println("################"); userDao.add("test002", 21); }
    Processed: 0.013, SQL: 10