日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

Spring @Transaction 注解執(zhí)行事務(wù)的流程

瀏覽:46日期:2023-07-06 15:07:11
前言

相信小伙伴一定用過 @Transaction 注解,那 @Transaction 背后的秘密又知道多少呢?

Spring 是如何開啟事務(wù)的?又是如何進(jìn)行提交事務(wù)和關(guān)閉事務(wù)的呢?

畫圖猜測

在開始 debug 閱讀源碼之前,小伙伴們應(yīng)該已經(jīng)知道 MySQL 是如何開啟事務(wù)的。

因此可以得出猜測:

Spring @Transaction 注解執(zhí)行事務(wù)的流程

那下面跟著源碼一起讀一讀,Spring 的 @Transaction 注解是如何執(zhí)行事務(wù)邏輯的?

Spring 事務(wù)執(zhí)行流程

開啟事務(wù)

這里使用的是 Spring Boot + MySQL + Druid

<dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.6</version></dependency>

Spring @Transaction 注解執(zhí)行事務(wù)的流程

在創(chuàng)建 Bean 的時(shí)候,會對 UserService 基于 AOP 生成代理對象;

AbstractAutowireCapableBeanFactory#initializeBean...wrapIfNecessaryAbstractAutoProxyCreator#createProxyCglibAopProxy#getProxy 生成代理對象

開始執(zhí)行 userService.updateUserInfo(); 這里的 userService 就是代理對象;會被 CglibAopProxy.DynamicAdvisedInterceptor#intercept 方法攔截; TransactionInterceptor#invoke 被事務(wù)攔截器攔截 TransactionAspectSupport#invokeWithinTransaction 事務(wù)處理 AbstractPlatformTransactionManager#getTransaction 會在這里調(diào)用 AbstractPlatformTransactionManager#startTransaction 方法,來開啟事務(wù)。

Spring @Transaction 注解執(zhí)行事務(wù)的流程

是不是看到 doBegin 這個(gè)詞突然感覺很熟悉。

跟進(jìn) DataSourceTransactionManager#doBegin 方法,注意看,此時(shí)是在 spring-jdbc-5.3.8.jar 包下面的。

Spring @Transaction 注解執(zhí)行事務(wù)的流程

因?yàn)槭褂玫?druid 連接池,所以這塊 Connection 是 durid 的連接池。

DruidPooledConnection#setAutoCommit(false) 關(guān)閉自動(dòng)提交;

這里就是 druid 的邏輯,一頓執(zhí)行然后到 com.alibaba.druid.filter.FilterChainImpl#connection_setAutoCommit。

Spring @Transaction 注解執(zhí)行事務(wù)的流程

ConnectionImpl#setAutoCommit,這個(gè)是在 mysql-connector-java-8.0.25.jar 包下的。

Spring @Transaction 注解執(zhí)行事務(wù)的流程

這一句才是重點(diǎn) SET autocommit=0。

SET autocommit=0

開啟事務(wù)了!

總結(jié)一下流程:

Spring @Transaction 注解執(zhí)行事務(wù)的流程

執(zhí)行 SQL

在開始事務(wù)之后,會通過回調(diào)執(zhí)行方法的內(nèi)部邏輯。

Spring @Transaction 注解執(zhí)行事務(wù)的流程

因?yàn)檫@里使用的是 Mybatis,所以還是會被代理,MapperProxy#invoke; DruidPooledPreparedStatement#execute; ClientPreparedStatement#execute;

Spring @Transaction 注解執(zhí)行事務(wù)的流程

執(zhí)行過程相對比較簡單:

Spring @Transaction 注解執(zhí)行事務(wù)的流程

提交事務(wù)

在 TransactionAspectSupport#invokeWithinTransaction 最后一行,commitTransactionAfterReturning(txInfo); 就是提交事務(wù)。

AbstractPlatformTransactionManager#commit 抽象事務(wù)管理器,進(jìn)行提交事務(wù) DataSourceTransactionManager#doCommit 數(shù)據(jù)源數(shù)據(jù)管理器,提交事務(wù)

Spring @Transaction 注解執(zhí)行事務(wù)的流程

這里肯定是調(diào)用連接池的方法,所以會執(zhí)行到 DruidPooledConnection 中

DruidPooledConnection commit 最終還是執(zhí)行到 mysql-connector-java-8.0.25.jar 包下面的 ConnectionImpl#commit

Spring @Transaction 注解執(zhí)行事務(wù)的流程

調(diào)用 commit 提交事務(wù)。

commit

Spring @Transaction 注解執(zhí)行事務(wù)的流程

異常回滾

異常在這里 TransactionAspectSupport#invokeWithinTransaction 會被 catch。

Spring @Transaction 注解執(zhí)行事務(wù)的流程

AbstractPlatformTransactionManager#rollback 在這里進(jìn)行 rollback

Spring @Transaction 注解執(zhí)行事務(wù)的流程

執(zhí)行 DataSourceTransactionManager#doRollback

最終執(zhí)行到 mysql-connector-java-8.0.25.jar 的 ConnectionImpl#rollback() 到 ConnectionImpl#rollbackNoChecks

Spring @Transaction 注解執(zhí)行事務(wù)的流程

從而執(zhí)行 rollback 語句

rollback

Spring @Transaction 注解執(zhí)行事務(wù)的流程

恢復(fù) autocommit

cleanupTransactionInfo(txInfo);

在 這個(gè)方法中會將之前設(shè)置的 autocommit 進(jìn)行恢復(fù)。

Java 原生開啟事務(wù)

如果覺得這樣有點(diǎn)繞,那咱們可以看簡單版本的,不帶 Spring。

/** * @author liuzhihang * @date 2021/6/18 16:51 */public class MainTest { public static void main(String[] args) throws Exception {DruidDataSource dataSource = new DruidDataSource();dataSource.setDriverClassName('com.mysql.cj.jdbc.Driver');dataSource.setUrl('jdbc:mysql://localhost:3306/demo');dataSource.setUsername('root');dataSource.setPassword('root');Connection connection = dataSource.getConnection();try { // 關(guān)閉自動(dòng)提交 connection.setAutoCommit(false); connection.prepareStatement('update user_info set user_name = ’liuzhihang’ where user_id = ’1001’;').executeUpdate(); connection.prepareStatement('update user_address set address = ’anhui’ where user_id = ’1001’;').executeUpdate(); // 提交事務(wù) connection.commit();} catch (Exception e) { // 回滾 connection.rollback();} finally { // 開啟自動(dòng)提交 connection.setAutoCommit(true);} }}

看完 Java 原生提交事務(wù)的方式,是不是感覺簡單明了。

Spring @Transaction 只是創(chuàng)建了 AOP 代理,通過代理調(diào)用原生的開啟關(guān)閉事務(wù),同樣在執(zhí)行 SQL 那一塊,也是 Mybatis 進(jìn)行了代理,從而提交 SQL。

總結(jié)

最后,將圖進(jìn)行合并,總結(jié)流程。

Spring @Transaction 注解執(zhí)行事務(wù)的流程

至此,事務(wù)執(zhí)行過程分析完畢。

不過還是有一個(gè)疑問?

為什么使用 set autocommit = 0 來開啟事務(wù),而不是使用 begin 或者 start transaction 來開啟事務(wù)呢?

以上就是Spring @Transaction 注解執(zhí)行事務(wù)的流程的詳細(xì)內(nèi)容,更多關(guān)于Spring @Transaction 注解的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Spring
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产欧美在线| 国产伦理久久久久久妇女| 国产精品国产一区| 精品日韩在线| 午夜国产欧美理论在线播放| 香蕉国产精品| 日本不卡一二三区黄网| 美女视频一区在线观看| 国产精品精品国产一区二区| 日韩一区欧美| 欧美网站在线| 久久精品av麻豆的观看方式| 国产不卡av一区二区| 欧美 日韩 国产一区二区在线视频| 91久久中文| 国产精品色在线网站| 亚洲天堂免费电影| 蜜臀av国产精品久久久久| 欧美黄色一区| 香蕉久久夜色精品国产| 久久国产精品免费一区二区三区| 成人国产综合| 亚洲精品少妇| 亚洲性色av| 日本不卡视频在线观看| 久久尤物视频| 亚洲区第一页| 免费视频国产一区| 牛牛精品成人免费视频| 久久一二三区| 日本不卡免费高清视频在线| 日韩国产精品久久久久久亚洲| 日韩深夜视频| 国产精品调教| 亚洲主播在线| 久久久精品网| 欧美一级鲁丝片| 久久三级中文| 日本麻豆一区二区三区视频| 久久精品国产亚洲夜色av网站| 国产日韩欧美一区二区三区| 人人精品人人爱| 在线精品小视频| 久久精品亚洲欧美日韩精品中文字幕| 欧美激情日韩| 久久精品99国产精品| 在线精品亚洲| 亚洲精品欧美| 亚洲精品婷婷| 日本va欧美va欧美va精品| 亚洲欧美网站在线观看| 蜜臀av性久久久久蜜臀aⅴ流畅| 亚洲在线网站| 综合激情在线| 蜜桃91丨九色丨蝌蚪91桃色| 999在线观看精品免费不卡网站| 99国产精品免费视频观看| 色婷婷久久久| 免费观看久久av| 蜜臀av亚洲一区中文字幕| 色综合视频一区二区三区日韩| 婷婷精品在线| 久久xxx视频| 新版的欧美在线视频| 亚洲先锋成人| 亚洲精品在线二区| 国产精品一区二区免费福利视频| 麻豆一区二区99久久久久| 国内精品麻豆美女在线播放视频| 欧美激情麻豆| 电影天堂国产精品| 免费日本视频一区| 国产精品亚洲产品| 日韩国产欧美一区二区| 在线国产一区| 国产美女视频一区二区| 成人亚洲一区| 蜜臀精品久久久久久蜜臀 | 国内激情久久| 国产午夜精品一区二区三区欧美| 日韩欧美中文字幕在线视频| 国产精品18| 国产va在线视频| 免费在线成人网| 国产粉嫩在线观看| 日韩中文字幕视频网| 麻豆国产欧美日韩综合精品二区| 色婷婷久久久| 日韩av网站在线免费观看| 麻豆精品新av中文字幕| 日韩午夜av在线| 狠狠久久伊人| 日本午夜精品久久久| 99免费精品| 国产乱人伦丫前精品视频| 伊人精品一区| 久久亚洲精精品中文字幕| 99久久婷婷| 麻豆一区二区99久久久久| 老牛影视一区二区三区| 中文字幕在线免费观看视频| 香蕉久久一区| 老司机精品久久| 久久男人av资源站| 麻豆91精品| 激情综合五月| 亚洲精品三级| 蜜桃视频免费观看一区| 久久久蜜桃一区二区人| 日韩中文字幕视频网| 欧美.日韩.国产.一区.二区| 久久69成人| 亚洲精品高潮| 亚洲制服少妇| 久久国产88| 九九综合九九| 丝袜av一区| 欧美肉体xxxx裸体137大胆| 欧美国产偷国产精品三区| 国产精品18| 成人午夜网址| av日韩中文| 精品国产第一福利网站| 精品视频在线你懂得| 美女国产精品久久久| 美女毛片一区二区三区四区最新中文字幕亚洲 | 久久精品高清| 久久不见久久见免费视频7| 中文字幕一区二区三区四区久久| 精品在线91| 免费精品视频最新在线| 亚洲精品韩国| 国产精品三级| 久久亚州av| 91精品推荐| 久久久影院免费| 午夜在线精品偷拍| 日韩精品免费视频一区二区三区 | 日本精品不卡| 中文日韩欧美| 欧美一区网站| 日韩在线不卡| 综合一区av| 精品视频亚洲| 精品中文字幕一区二区三区av| 日韩制服丝袜先锋影音| 日韩精品亚洲一区二区三区免费| 精品一区二区三区四区五区| 精品视频在线观看网站| 亚洲福利专区| 久久精品xxxxx| 欧美性感美女一区二区| 日韩极品在线观看| 日韩欧美少妇| 久久国产乱子精品免费女| 播放一区二区| 日韩av在线免费观看不卡| 91精品一区二区三区综合在线爱 | 你懂的国产精品| 国产精品日韩久久久| 日韩1区2区3区| 亚洲午夜黄色| 日本久久综合| 欧美日韩亚洲一区三区| 国产在线不卡| 国产一区一一区高清不卡| 日本伊人久久| 三级亚洲高清视频| 91看片一区| 精品视频91| 日韩一区二区三区精品| 国产精品人人爽人人做我的可爱| аⅴ资源天堂资源库在线| 国产毛片久久久| 日韩中文字幕一区二区高清99| 中文一区一区三区高中清不卡免费| 国产日韩欧美| 日韩国产一区二| 蜜臀久久99精品久久久久宅男 | 日韩激情一二三区| 亚洲精品极品| 亚洲日韩视频| 四虎国产精品免费久久| 久久亚洲不卡| 最新国产精品视频| 日韩欧美在线精品| 日韩在线观看一区二区| 免费久久99精品国产自在现线| 午夜日韩av| 久久亚洲视频| 日韩av午夜在线观看| 国产亚洲一区| 成人在线丰满少妇av| 97视频热人人精品免费| 成人福利av| 在线精品视频在线观看高清| 国产女优一区| 国产欧美69| 日韩在线欧美| 亚洲一区欧美二区|