面试官:问你一个,Spring事务是如何传播的?
推荐学习
- 肝了十天半月 , 献上纯手绘“Spring/Cloud/Boot/MVC”全家桶脑图
- 疯狂膜拜!阿里出品Spring Security王者晋级文档
- 真香警告!Alibaba珍藏版mybatis手写文档 , 刷起来
文章插图
前言Spring事务是如何传播的?
其实之前有分析事务注解的解析过程 , 本质上是将事务封装为切面加入到AOP的执行链中 , 因此会调用到MethodInceptor的实现类的invoke方法 , 而事务切面的Interceptor就是TransactionInterceptor , 所以本篇直接从该类开始 。
事务切面的调用过程
public Object invoke(MethodInvocation invocation) throws Throwable {// Work out the target class: may be {@code null}.// The TransactionAttributeSource should be passed the target class// as well as the method, which may be from an interface.Class> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);// Adapt to TransactionAspectSupport's invokeWithinTransaction...return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed); }
这个方法本身没做什么事 , 主要是调用了父类的invokeWithinTransaction方法 , 注意最后一个参数 , 传入的是一个lambda表达式 , 而这个表达式中的调用的方法应该不陌生 , 在分析AOP调用链时 , 就是通过这个方法传递到下一个切面或是调用被代理实例的方法 , 忘记了的可以回去看看 。 protected Object invokeWithinTransaction(Method method, @Nullable Class> targetClass,final InvocationCallback invocation) throws Throwable {// If the transaction attribute is null, the method is non-transactional.//获取事务属性类 AnnotationTransactionAttributeSourceTransactionAttributeSource tas = getTransactionAttributeSource();//获取方法上面有@Transactional注解的属性final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);//获取事务管理器final PlatformTransactionManager tm = determineTransactionManager(txAttr);final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);Object retVal = null;try {// 调用proceed方法retVal = invocation.proceedWithInvocation();}catch (Throwable ex) {// target invocation exception//事务回滚completeTransactionAfterThrowing(txInfo, ex);throw ex;}finally {cleanupTransactionInfo(txInfo);}//事务提交commitTransactionAfterReturning(txInfo);return retVal;}// 省略了else }
这个方法逻辑很清晰 , 一目了然 , if里面就是对声明式事务的处理 , 先调用createTransactionIfNecessary方法开启事务 , 然后通过invocation.proceedWithInvocation调用下一个切面 , 如果没有其它切面了 , 就是调用被代理类的方法 , 出现异常就回滚 , 否则提交事务 , 这就是Spring事务切面的执行过程 。 但是 , 我们主要要搞懂的就是在这些方法中是如何管理事务以及事务在多个方法之间是如何传播的 。事务的传播性概念传播性是Spring自己搞出来的 , 数据库是没有的 , 因为涉及到方法间的调用 , 那么必然就需要考虑事务在这些方法之间如何流转 , 所以Spring提供了7个传播属性供选择 , 可以将其看成两大类 , 即是否支持当前事务:
推荐阅读
- 微软Edge迎来一个新的浮层菜单 用于管理下载进度
- 一个亮点解读 创维小湃P3 Pro必须要买的理由
- 华为认证HCIP-GaussDB-OLTP发布,下一个高级DBA会是你吗
- 又黄一个APP,“品牌收购机”成“没落收割机”,收一黄一
- 教你用Siri来控制电脑:真香
- Google AI建立了一个能够分析烘焙食谱的机器学习模型
- 虾米音乐宣布2月5日关停 人们更关心谁将是下一个
- 虾米音乐一个月后关停 我的听歌记录和个人信息怎么办?
- 华为隐藏一个会议神器,一分钟录入1000字,打字慢的可以看看
- 荣耀手环6简评:这是一个有“偏见”的产品