一、问题复现

1.场景

2个service方法, 方法A中调用方法B。

方法A 是核心业务方法,涉及多张表数据变更,为了保持数据一致,用spring事务注解:@Transactional(rollbackFor = Exception.class)

方法B 比较耗时,为了不影响核心业务,方法B 用@Async注解,单独开启一个线程去异步执行。(方法B在另外一个类里边,不能和A在同一个类)。

2.出错原因

方法B是异步方法,导致方法A事务还没提交时(不一定出错,具体就看哪个线程执行的快了)方法B就执行了。

3.期望

期望方法A上的大事务commit后再执行方法B。

二、解决方案

 // 注册事务同步处理
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit() {
// 事务提交完毕时,触发:funcB
funB();
}

三、原理

提交一个事务同步处理,在事务commit之后执行,具体存放在threadLocal(线程本地变量)中,事务commit时会去threadLocal里边取。源码afterCommit是空的,没有任何操作,可见是spring专门预留给大家使用的。

源码:

TransactionSynchronizationAdapter是一个接口适配器,这样不用实现接口的全部方法,按需Override即可。类图如下图所示:

TransactionSynchronizationAdapter实现了2个接口:

  • TransactionSynchronization事务同步接口,
  • Ordered执行优先级

我们这里就是实现了TransactionSynchronization接口的afterCommit()方法,最终在事务commit提交后执行。
关于spring事务执行过程图:

四、总结

遇到问题后,很快就想到了处理方式,因为我提前储备了相关知识

1.spring事务系列(具体在第三章 事务源码,里边有链接)

spring事务详解(一)初探事务

2.@Async实现异步

异步任务spring @Async注解源码解析

3.threadLocal线程本地变量

ThreadLocal终极源码剖析-一篇足矣!

Transactional事务提交后触发异步方法的更多相关文章

  1. spring执行事务提交后进行一些逻辑操作

    在使用spring事务时,我们通常会把事务内的所有操作当成是一个原子操作.也就是当整个事务内的所有代码都执行完成后, 才会将所有的数据落实到数据库中.这样做有时也会给我们造成麻烦.比如以下场景: 根据 ...

  2. mysql源码解读之事务提交过程(一)

    mysql是一种关系型数据库,关系型数据库一个重要的特性就是支持事务,这是区别于no-sql产品的一个核心特性.当然了,no-sql产品支持键值查询,不能支持sql语句,这也是一个区别.今天主要讨论下 ...

  3. MySQL事务提交过程(一)

    MySQL作为一种关系型数据库,已被广泛应用到互联网中的诸多项目中.今天我们来讨论下事务的提交过程. MySQL体系结构 由于mysql插件式存储架构,导致开启binlog后,事务提交实质是二阶段提交 ...

  4. MySQL事务提交过程

    一.MySQL事务提交过程(一) MySQL作为一种关系型数据库,已被广泛应用到互联网中的诸多项目中.今天我们来讨论下事务的提交过程. 由于mysql插件式存储架构,导致开启binlog后,事务提交实 ...

  5. 为DbContextScope添加数据库事务提交完成事件

    使用EF开发应用程序的一个难点就在于对其DbContext的生命周期管理,你的管理策略是否能很好的支持上层服务 使用独立事务,使用嵌套事务,并行执行,异步执行等需求? Mehdi El Gueddar ...

  6. Gitlab源码库里代码提交后,如何触发jenkins自动构建?

    版本库里代码提交后,如何触发jenkins自动构建?这是一个面试题,感觉自己回答的并不好,因为并没有用过这个功能,之前公司实际项目用的是svn版本管理,一般都用立刻构建,和定时任务构建(不管代码是否有 ...

  7. spring @Transactional 事务注解

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE, rollbackFor = ...

  8. @Transactional 事务注解

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE, rollbackFor = ...

  9. Spring提取@Transactional事务注解的源码解析

    声明:本文是自己在学习spring注解事务处理源代码时所留下的笔记: 难免有错误,敬请读者谅解!!! 1.事务注解标签 <tx:annotation-driven /> 2.tx 命名空间 ...

随机推荐

  1. Timus-1005. Stone Pile-01背包

    传送门:http://acm.timus.ru/problem.aspx?space=1&num=1005 参考:https://www.cnblogs.com/yinzm/p/6629222 ...

  2. 左偏树 P3377【模板】左偏树(可并堆)

    题目传送门 代码: /* code by: zstu wxk time: 2019/03/01 */ #include<bits/stdc++.h> using namespace std ...

  3. Dungeon Master POJ - 2251 [kuangbin带你飞]专题一 简单搜索

    You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of un ...

  4. watch命令的监控结果输出到文件

    watch命令是为命令行输出设计的工具,其结果包含很多不可打印的字符,所以输出重定向到文件中很不方便,比如这样做的话有很多乱码: (watch -n 60 <mycommand> ) &g ...

  5. springboot应用监控和管理

    spring boot应用监控和管理 Spring Boot 监控核心是 spring-boot-starter-actuator 依赖,增加依赖后, Spring Boot 会默认配置一些通用的监控 ...

  6. 记一次神奇的sql查询经历,group by慢查询优化

    一.问题背景 现网出现慢查询,在500万数量级的情况下,单表查询速度在30多秒,需要对sql进行优化,sql如下: 我在测试环境构造了500万条数据,模拟了这个慢查询. 简单来说,就是查询一定条件下, ...

  7. 基于STC89C52的oled红外遥控闹钟

    这个红外遥控主要是程序通过对按下的键的键码进行解析,并运行相应的功能代码 一次按键动作的遥控编码信息为 32 位串行二进制码.对于二进制信号“0”,一个脉冲占 1.2ms:对于二进制信号“1”,一个脉 ...

  8. Java 中的 syncronized 你真的用对了吗

    生活中随处可见并行的例子,并行 顾名思义就是一起进行的意思,同样的程序在某些时候也需要并行来提高效率,在上一篇文章中我们了解了 Java 语言对缓存导致的可见性问题.编译优化导致的顺序性问题的解决方法 ...

  9. Elastic Stack 笔记(四)Elasticsearch5.6 索引及文档管理

    博客地址:http://www.moonxy.com 一.前言 在 Elasticsearch 中,对文档进行索引等操作时,既可以通过 RESTful 接口进行操作,也可以通过 Java 也可以通过 ...

  10. Cabloy-CMS:动静结合,解决Hexo痛点问题

    介绍 Cabloy-CMS是什么 Cabloy-CMS是基于CabloyJS全栈业务开发框架开发的"动静结合"的CMS,可以快速构建企业网站.博客.社区.商城等Web应用. 在线演 ...