spring事务@Transactional实现原理

spring是如何实现事务的 AOP + 动态代理
使用AOP拦截到我们加了@myAnnoTrancation的方法 然后开启事务 使用动态代理调用当前方法 提交事务 同时使用AOP异常通知 做回滚的监听


1.自定义注解

@Target(value={ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface MyAnnoTrancation {

}

 

2.事务管理

@Component
public class MyTransactionManager {

    private TransactionStatus transactionStatus;

    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;

    /**
     * 开启事务
     */
    public TransactionStatus begin() {
        TransactionStatus status = dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());
        return status;
    }

    /**
     * 事务回滚
     **/

    public void rollBack() {
        System.out.println("事务回滚");
        dataSourceTransactionManager.rollback(transactionStatus);
    }

    /**
     * 事务提交
     **/
    public void commit(TransactionStatus transactionStatus) {
        dataSourceTransactionManager.commit(transactionStatus);
    }

}

 

3.针对事务的拦截处理

@Aspect
@Component
@Transactional
public class MyAopTransaction  {
    @Autowired
    private MyTransactionManager myTransactionManager;

    TransactionStatus transactionStatus = null;

    // ProceedingJoinPoint AOP获取连接到对象
    @Around("execution(* com.sunny.service.StudentService*.*(..))")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        System.out.println("拦截起作用");
        // 先获取拦截的方法 判断方法上有没有@Transaction注解
        MyAnnoTrancation myAnnoTrancation = geMyAnnoTrancation(point);

        // 开启事务
        if (myAnnoTrancation != null) {
            transactionStatus = myTransactionManager.begin();
        }
        // 调用拦截方法
        Object proceed = point.proceed();

        if (myAnnoTrancation != null) {
            myTransactionManager.commit(transactionStatus);
        }

        point.getClass().getAnnotations();
        return proceed;
    }


    /**
     * 异常通知进行 回滚事务
     */
    @AfterThrowing(throwing = "ex", pointcut = "execution(* com.sunny.service.StudentService*.*(..))")
    public void afterThrowing(JoinPoint point, Throwable ex) {
        System.out.println("异常捕获" + ex.getMessage());
        // 获取当前事务 直接回滚
        if (transactionStatus != null) {
            myTransactionManager.rollBack();
        }

    }

    // 获取拦截对象释放被打上 自定义注解
    public MyAnnoTrancation geMyAnnoTrancation(ProceedingJoinPoint point) {
        String methodName = point.getSignature().getName();
        Class<? extends Object> classTarget = point.getTarget().getClass();
        try {
            Method method = classTarget.getMethod(methodName, classTarget.getClasses());
            MyAnnoTrancation myannotation = method.getAnnotation(MyAnnoTrancation.class);
            if (myannotation != null) {
                return myannotation;
            }
            return null;
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
        return null;

    }

}

 

4.使用

    @MyAnnoTrancation
    public void add() {
        userDao.add("test001", 20);
        int i = 1 / 0;
        System.out.println("################");
        userDao.add("test002", 21);
    }

 

posted @ 2020-08-23 18:13  爵士灬  阅读(1179)  评论(0)    收藏  举报