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); }

浙公网安备 33010602011771号