Java Spring AOP源碼解析之事務實現原理

不用Spring管理事務?

讓我們先來看一下不用spring管理事務時,各種框架是如何管理事務的

使用JDBC來管理事務

在這裡插入圖片描述

使用Hibernate來管理事務

在這裡插入圖片描述

業務邏輯和事務代碼是耦合到一塊的,並且和框架的具體api綁定瞭。當我們換一種框架來實現時,裡面對事務控制的代碼就要推倒重寫,並不一定能保證替換後的api和之前的api有相同的行為。

基於這些問題,Spring抽象瞭一些事務相關的頂層接口,我們面向接口編程,換框架時隻要換具體的實現即可。有點像JDBC API的味道瞭

在這裡插入圖片描述

常用api 接口
PlatformTransactionManager 對事務進行管理
TransactionDefinition 定義事務的相關屬性,例如隔離級別,傳播行為
TransactionStatus 保存事務狀態

針對不同的數據訪問技術,使用不用的PlatformTransactionManager類即可

數據訪問技術 PlatformTransactionManager實現類
JDBC/Mybatis DataSourceTransactionManager
Hibernate HibernateTransactionManager
Jpa JpaTransactionManager
Jms JmsTransactionManager

編程式事務管理

使用PlatformTransactionManager

在這裡插入圖片描述

在這裡插入圖片描述

在這裡插入圖片描述

使用TransactionTemplate

當我們直接使用PlatformTransactionManager來管理事務時,有很多模版代碼。例如業務代碼正常執行,提交事務,否則回滾事務。我們可以把這部分模版代碼封裝成一個模版類,這樣使用起來就很方便瞭,如下所示

在這裡插入圖片描述

如下圖所示,TransactionTemplate#execute方法就是一個典型的模版方法

在這裡插入圖片描述

我們可以傳入如下2個接口的實現類來執行業務邏輯,TransactionCallback(需要返回執行結果)或TransactionCallbackWithoutResult(不需要返回結果)

聲明式事務管理

為瞭讓使用更加簡潔,Spring直接把事務代碼的執行放到切面中瞭,我們隻需要在業務代碼方法上加上一個@Transactional註解即可,這種方式我們最常用哈

使用@Transactional註解

此時事務相關的定義我們就可以通過@Transactional註解來設置瞭

屬性名 類型 描述 默認值
value(和transactionManager互為別名) String 當在配置文件中有多個PlatformTransactionManager ,用該屬性指定選擇哪個事務管理器 空字符串""
propagation 枚舉:Propagation 事務的傳播行為 REQUIRED
isolation 枚舉:Isolation 事務的隔離度 DEFAULT
timeout int 事務的超時時間。如果超過該時間限制但事務還沒有完成,則自動回滾事務 -1
readOnly boolean 指定事務是否為隻讀事務 false
rollbackFor Class[] 需要回滾的異常 空數組{}
rollbackForClassName String[] 需要回滾的異常類名 空數組{}
noRollbackFor Class[] 不需要回滾的異常 空數組{}
noRollbackForClassName String[] 不需要回滾的異常類名 空數組{}

在這裡插入圖片描述

源碼解析

我們需要在配置類上加上@EnableTransactionManagement註解,來開啟spring事務管理功能,@EnableTransactionManagement最主要的功能就是註入一個TransactionInterceptor攔截器,來控制事務開啟,提交或者回滾

ProxyTransactionManagementConfiguration

在這裡插入圖片描述

TransactionInterceptor#invoke

在這裡插入圖片描述

TransactionAspectSupport#invokeWithinTransaction

在這裡插入圖片描述

TransactionAspectSupport#createTransactionIfNecessary

在這裡插入圖片描述

當開啟事務的時候,可以看到各種傳播屬性的行為

AbstractPlatformTransactionManager#getTransaction

在這裡插入圖片描述

Spring事務的傳播行為在Propagation枚舉類中定義瞭如下幾種選擇

支持當前事務

  • REQUIRED :如果當前存在事務,則加入該事務。如果當前沒有事務,則創建一個新的事務
  • SUPPORTS:如果當前存在事務,則加入該事務 。如果當前沒有事務, 則以非事務的方式繼續運行
  • MANDATORY :如果當前存在事務,則加入該事務 。如果當前沒有事務,則拋出異常

不支持當前事務

  • REQUIRES_NEW :創建一個新事務,如果當前存在事務,則把當前事務掛起
  • NOT_SUPPORTED : 以非事務方式運行,如果當前存在事務,則把當前事務掛起
  • NEVER : 以非事務方式運行,如果當前存在事務,則拋出異常

其他情況

  • NESTED :如果當前存在事務,則創建一個事務作為當前事務的嵌套事務來執行 。如果當前沒有事務,則該取值等價於REQUIRED

以NESTED啟動的事務內嵌於外部事務中 (如果存在外部事務的話),此時內嵌事務並不是一個獨立的事務,它依賴於外部事務。隻有通過外部事務的提交,才能引起內部事務的提交,嵌套的子事務不能單獨提交

參考博客

https://www.jb51.net/article/229456.htm

總結

本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!

推薦閱讀: