TransactionAspectSupport#invokeWithinTransaction

TransactionAspectSupport#invokeWithinTransaction 是 Spring 对处理的处理。下面我们来大概分析一下它的处理过程:

上面的代码逻辑如下:

  • TransactionAttributeSource#getTransactionAttribute 获取事务相关的信息(TransactionAttribute),以注解型事务为例,看方法获取类上有没有标注@Transactional注解。

  • 获取到 Spring 容器中配置的事务管理器 (PlatformTransactionManager),后面就是真正的事务处理

  • 创建事务信息(TransactionInfo),里面包含事务管理器(PlatformTransactionManager) 以及事务相关信息(TransactionAttribute)

  • 后面就是 Spring 对于事务的抽象操作,包含设置自动提交 false、业务操作、异常回滚事务和正常就提交事务

我们回到正题, Spring 通过创建事务信息(TransactionInfo),把数据库连接通过 TransactionSynchronizationManager#bindResource 绑定到 ThreadLocal 变量当中。然后标注到一个事务当中的其它数据库操作就可以通过TransactionSynchronizationManager#getResource 获取到这个连接。

数据库的事务是基于连接的,Spring 对于多个数据库操作的事务实现是基于 ThreadLocal。所以在事务操作当中不能使用多线程

3、Spring 事务的扩展 – TransactionSynchronization

在上面的 TransactionSynchronizationManager 类中我们知道,事务操作的时候它的当前线程还保存了 TransactionSynchronization 对象。而这个对象伴随着 Spring 对 事务处理的各个生命周期都会有相应的扩展。

TransactionSynchronization.java


public interface TransactionSynchronization extends Flushable {/** 事务提交状态 */int STATUS_COMMITTED = 0;/** 事务回滚状态 */int STATUS_ROLLED_BACK = 1;/**系统异常状态 */int STATUS_UNKNOWN = 2;void suspend();void resume();void flush();// 事务提交之前void beforeCommit(boolean readOnly);// 事务成功或者事务回滚之前void beforeCompletion();// 事务成功提交之后void afterCommit();// 操作完成之后(包含事务成功或者事务回滚)void afterCompletion(int status);}

事务的事务扩展项目中的应用场景是当订单成功之后,发送一条消息到 MQ 当中去。由于事务是和数据库连接相绑定的,如果把发送消息和数据库操作放在一个事务里面。当发送消息时间过长时会占用数据库连接,所以就要把数据库操作与发送消息到 MQ 解耦开来。可以利用 TransactionSynchronization#afterCommit 的这个方法,当数据成功保存到数据库并且事务提交了就把消息发送到 MQ 里面。


@Transactional
public void finishOrder(Order order){// 修改订单成功updateOrderSuccess(order);// 发送消息到 MQTransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter(){@Overridepublic void afterCommit() {mqService.send(order);}});
}

当事务成功提交之后,就会把消息发送给 MQ,并且不会占用数据库连接资源。

4、Spring 事务扩展 – @TransactionalEventListener

在 Spring framework 4.2 之后还可以使用@TransactionalEventListener处理数据库事务提交成功后再执行操作。这种方式比 TransactionSynchronization 更加优雅。它的使用方式如下:

@Transactionalpublic void finishOrder(Order order){// 修改订单成功updateOrderSuccess(order);// 发布 Spring Event 事件applicationEventPublisher.publishEvent(new MyAfterTransactionEvent(order));}@Slf4j@Componentprivate static class MyTransactionListener {@Autowiredprivate MqService mqService;@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)private void onHelloEvent(MyAfterTransactionEvent event) {Order order = event.getOrder();mqService.send(order);}}// 定一个事件,继承自ApplicationEvent private static class MyAfterTransactionEvent extends ApplicationEvent {private Order order;public MyAfterTransactionEvent(Object source, Order order) {super(source);this.order = order;}public Order getOrder() {return order;}}

它的实现原理是当 Spring Bean 的方法标注了通过 TransactionalEventListenerFactory#createApplicationListener创建 ApplicationListenerMethodTransactionalAdapter 然后在事件回调当中创建 TransactionSynchronization的实现类TransactionSynchronizationEventAdapter。并且通过 TransactionSynchronizationManager.registerSynchronization 把 TransactionSynchronizationEventAdapter 注册到当前线程当中。

TransactionSynchronizationEventAdapter

private static class TransactionSynchronizationEventAdapter extends TransactionSynchronizationAdapter {private final ApplicationListenerMethodAdapter listener;private final ApplicationEvent event;private final TransactionPhase phase;public TransactionSynchronizationEventAdapter(ApplicationListenerMethodAdapter listener,ApplicationEvent event, TransactionPhase phase) {this.listener = listener;this.event = event;this.phase = phase;}@Overridepublic int getOrder() {return this.listener.getOrder();}@Overridepublic void beforeCommit(boolean readOnly) {if (this.phase == TransactionPhase.BEFORE_COMMIT) {processEvent();# 最后现在其实从大厂招聘需求可见,在招聘要求上有高并发经验优先,包括很多朋友之前都是做传统行业或者外包项目,一直在小公司,技术搞的比较简单,没有怎么搞过分布式系统,但是现在互联网公司一般都是做分布式系统。所以说,如果你想进大厂,想脱离传统行业,这些技术知识都是你必备的,下面自己手打了一份Java并发体系思维导图,希望对你有所帮助。**[资料获取方式:戳这里免费下载](https://gitee.com/vip204888/java-p7)**较简单,没有怎么搞过分布式系统,但是现在互联网公司一般都是做分布式系统。所以说,如果你想进大厂,想脱离传统行业,这些技术知识都是你必备的,下面自己手打了一份Java并发体系思维导图,希望对你有所帮助。**[资料获取方式:戳这里免费下载](https://gitee.com/vip204888/java-p7)**![](https://img-blog.csdnimg.cn/img_convert/d8c9b612ad20b889af080d1480d0bc3f.png)

Java面试必问!Spring事务扩展机制(2)相关推荐

  1. Java 面试必问题目,Java 后端校招面试题

    字节跳动一面: 自我介绍,主要讲讲做了什么和擅长什么 看你项目做 Spring 比较多, 问一下 Spring 相关的东西, IoC 是什么概念? Bean 的默认作用范围是什么?其他的作用范围? 索 ...

  2. 面试必问:JVM类加载机制详细解析

    前言 在Java面试中,简历上有写JVM(Java虚拟机)相关的东西,JVM的类加载机制基本是面试必问的知识点. 类的加载和卸载 JVM是虚拟机的一种,它的指令集语言是字节码,字节码构成的文件是cla ...

  3. Java面试必问!javasocket服务端持久化

    前言 最近刷到了一句耐人寻味的话,"解决雪崩问题的最好办法是不发生雪崩". 不论是在硅谷互联网公司里还是在国内的互联网平台上,曾多次遇到过海量规模的交易瞬间吞噬平台的悲惨故事. 核 ...

  4. 面试必问的 JVM 类加载机制,你懂了吗?

    前言 本次带来 JVM 的另一块重要内容,类加载机制,不废话,直接开怼. 正文 1.类加载的过程. 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载.验证.准备.解析.初始化 ...

  5. 今年Java面试必问的这些技术面,看完这一篇你就懂了

    说明 Java生鲜电商平台中由于采用了微服务架构进行业务的处理,买家,卖家,配送,销售,供应商等进行服务化,但是不可避免存在分布式事务的问题. 业界有很多的解决方案,对此我相信大家都百度一下子就有很多 ...

  6. Java面试必问的HashMap,java软件工程师面试话术

    前言 我们从一个问题引入今天的主题. 在日常业务开发中,我们可能经常听到 DBA 对我们说"不要"(注意:不是禁止)使用 join,那么为什么 DBA 对 join 这么抵触呢?是 ...

  7. 继续卷!面试又问Spring 事务有几种传播行为和隔离级别?

    怕什么真理无穷 进一步有近一步的欢喜 面试又被问到了事务,来吧,要么卷起来,要么躺平.卷不动躺平会不会导致数据不一致? 事务概念 事务是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序 ...

  8. 阿里Java面试必问:java多线程实例

    基于 Servlet 容器的 Web MVC 身为 Java 开发者,对于 Spring 框架并不陌生.它起源于 2002 年.Rod Johnson 著作<Expert One-on-One ...

  9. 网易Java面试必问:月薪20k+的Java面试都问些什么

    前言 不知道你们发现没有,在很多互联网公司基本上都是80后,90后居多,很少还有超过40岁的程序员.可能很多人心里都有一个疑问,那就是这些40多岁的程序员都干嘛去了呢?创业显然只是极少数的人,至于管理 ...

最新文章

  1. 第11届 蓝桥杯-第1、2次模拟(软件类)真题-(2020年3月、4月)-官方讲解视频
  2. Neo4j:在Neo4j浏览器的帮助下探索新数据集
  3. [PALAPALA] 无题 - 外来的和尚会念经
  4. 努力只是因为想去做想做的事
  5. java.lang.ClassNotFoundException: org.apache.commons.lang.exception.NestableRunt
  6. spring-boot 整合redis作为数据缓存
  7. ASP.NET程序中 抛出Thread was being aborted. 异常(转)
  8. PWM波转DC直流之二阶RC低通滤波器设计
  9. 洛谷 P1653 猴子 解题报告
  10. xss.haozi.me
  11. Photoshop-选区的应用
  12. 基于 OpenVINO™ 的 AI 视觉应用基础课学习笔记(三)深度学习简介
  13. FANUC机器人的主板结构和电缆连接示意图介绍
  14. php关注账号,一键关注微信公众平台账号
  15. Qt编写安防视频监控系统5-视频回放
  16. android 4.4 电池电量管理底层分析(C\C++层)
  17. xss labs 挑战之旅
  18. 【软件2.0】软件2.0时代来了!特斯拉AI负责人说:神经网络正在改变编程
  19. 提高晚上学习效率的11个方法
  20. vs数据库访问出现Object reference not set to an instance of an object. 错误解决办法

热门文章

  1. 水刀行业调研报告 - 市场现状分析与发展前景预测
  2. 浙大计算机学院绩点,浙江大学学分制管理暂行规定-浙江大学本科生院.doc
  3. 经常玩电脑正确的坐姿_「姿态训练」保持良好坐姿的八个步骤
  4. oracle窗口累计函数,oracle 窗口函数 (keep)
  5. 终于升级?89年的Linux内核C语言“跟上时代”转成现代C
  6. 从摩托罗拉、诺基亚再到航空领域应用,这款开源数据库的成功如何成就天才程序员?...
  7. 官宣!DolphinScheduler 毕业成为 Apache 软件基金会顶级项目
  8. 京东金融品牌升级,为用户做精准决策,打造金融机构的“第二增长场景”
  9. 完了!Oracle 被虐!MySQL 登顶 Top1!原来这么多人都在用
  10. 如何用 Python 画一个纸飞机?| 原力计划