聊一聊Spring中的 Transaction基本实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了聊一聊Spring中的 Transaction基本实现相关的知识,希望对你有一定的参考价值。
参考技术A 我们知道加一个 org.springframework.transaction.annotation.Transactional 注解便可以让改方法实现事务管理(提交/回滚), 但是我们知道一个如何用编码的方式实现事务如何回滚的 . 抛开动态代理 , 其实事务就是动态代理实现, 但是不是我们的重点 , 我们要讲讲他为啥只支持单个数据源 还有不支持 异步操作(这里的意思是在事务里开启一个新线程执行业务)一般操作都是下面这样子 , 基本流程
所以Spring帮助我们做的就是这个, 那么它一定也是这么实现的 .
如何启动事务呢 ,
首先需要加入依赖
SpringBoot 可以使用这个 org.springframework.transaction.annotation.EnableTransactionManagement ,对于XML配置可以去看看这个类, 他会教你咋配置 .
方法控制是依靠 @Transactional(transactionManager ="TransactionManager") ,
然后我们需要自己自定义实现一个 org.springframework.transaction.PlatformTransactionManager Bean , 告诉spring事务处理的使用哪个
那么为啥加了个注解就会自动给你管理事务了呢 , 他难道不是这么做的吗.
其实看 org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration 这个地方
在你单数据源的情况下, 同时自动注入情况下, 他会默认给你生成一个 DataSourceTransactionManager
所以默认情况下, 就是走这个, 现在我们绝地不看这个 . 我们要自己实现 .
我们的问题 .
我们定义俩数据源, 其中就需要俩 DataSourceTransactionManager
那么写我们的service
这样子启动绝对会GG , 因为你没指定有哪个 TransactionManager .
那么我们怎么做,
但是事务处理的时候 org.springframework.jdbc.datasource.DataSourceTransactionManager#doRollback
他有一个 Connection , 那么不和我们的connection一样 , 那么绝对回滚不了哇. 因为你不是一个连接, 所以根本题绝对提交成功了 , 那么为啥 Mybatis 可以呢 . 所以借鉴一下,
我们看MyBatis的实现 org.mybatis.spring.transaction.SpringManagedTransaction 在这里, 这里缩进不了了 , 他的tab是俩空格, 我是四个, 哎 . 就这么看吧
所以就是在获取这里 DataSourceUtils -> org.springframework.jdbc.datasource.DataSourceUtils#getConnection
doGetConnection(dataSource) -> org.springframework.jdbc.datasource.DataSourceUtils#doGetConnection
TransactionSynchronizationManager.getResource(dataSource); -> org.springframework.transaction.support.TransactionSynchronizationManager#getResource
doGetResource(actualKey); -> org.springframework.transaction.support.TransactionSynchronizationManager#doGetResource
其实 resources 就是啥, 就是一个 ThreadLocal 维护的一个线程对象,
所以这就是为啥说事务不支持异步的原因了, 只能一个线程执行一个事务 , 不能俩线程执行 , 比如说这种,绝对不行.
其实到这里我们就拿到了 ConnectionHolder 了 , org.springframework.jdbc.datasource.ConnectionHolder 其实就是一个连接持有者, 一层封装罢了 , 多了一些额外信息.
那么到这里他是如何加入进去的呢, 那就是
org.springframework.jdbc.datasource.DataSourceTransactionManager#doBegin 这个方法了
org.springframework.transaction.support.TransactionSynchronizationManager#bindResource
所以前前后后就是这个, 所以懂了吗
所以这就是 transaction 的内容 ,
我们观察源码 发现 Transaction 不支持异步操作 , 不支持单任务(单个请求)多数据源, 所以不能保证多数据源的事务相关问题 ,
因此下一期我讲解多数据源 (分库分表其实也是这样子) , 或者 微服务下多数据源问题 .
以上是关于聊一聊Spring中的 Transaction基本实现的主要内容,如果未能解决你的问题,请参考以下文章
#聊一聊悟空编辑器#spring框架事务相关知识点Spring框架教程
无规矩不成方圆,聊一聊 Spring Boot 中 RESTful 接口设计规范