Spring之@Transactional注解原理


一般情況下我們在處理具體的業務都是在Service層來進行處理操作,此時如果在Service類上添加@Transactional注解的話,那么Service曾的每一個業務方法調用的時候都會打開一個事務。

——————————————————————————————————————————————————

注意點: Spring默認情況下會對(RuntimeException)及其子類來進行回滾,在遇見Exception及其子類的時候則不會進行回滾操作。

————————————————————————————————————————————————————

注意點: @Transactional既可以作用於接口,接口方法上以及類已經類的方法上。但是Spring官方不建議接口或者接口方法上使用該注解,因為這只有在使用基於接口的代理時它才會生效。另外, @Transactional 注解應該只被應用到 public 方法上,這是由 Spring AOP 的本質決定的。如果你在 protected、private 或者默認可見性的方法上使用 @Transactional 注解,這將被忽略,也不會拋出任何異常。 Spring默認使用的是jdk自帶的基於接口的代理,而沒有使用基於類的代理CGLIB。

——————————————————————————————————————————————————————

重點注意點: @Transactional注解底層使用的是動態代理來進行實現的,如果在調用本類中的方法,此時不添加@Transactional注解,而是在調用類中使用thisi調用本類中的另外一個添加了@Transactional注解,此時this調用的方法上的@Transactional注解是不起作用的。

 

1. 讓Exception異常也進行回滾操作,在調用該方法前加上: @Transactional(rollbackFor = Exception.class)
2. 讓RuntimeException不進行回滾操作,在調用該方法前加上: @Transactional(rollbackFor = RuntimeException.class)

 

1. 在整個方法運行前就不會開啟事務: @Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true),這樣就做成一個只讀事務,可以提高效率

 

屬性 類型 描述
value String 可選的限定描述符,指定使用的事務管理器
propagation enum: Propagation 可選的事務傳播行為設置
isolation enum: Isolation 可選的事務隔離級別設置
readOnly boolean 讀寫或只讀事務,默認讀寫
timeout int (in seconds granularity) 事務超時時間設置
rollbackFor Class對象數組,必須繼承自Throwable 導致事務回滾的異常類數組
rollbackForClassName 類名數組,必須繼承自Throwable 導致事務回滾的異常類名字數組
oRollbackFor Class對象數組,必須繼承自Throwable 不會導致事務回滾的異常類數組
noRollbackForClassName 類名數組,必須繼承自Throwable 不會導致事務回滾的異常類名字數組

查看方法的是否事務已經被執行

TransactionSynchronizationManager.isActualTransactionActive()  返回true: 該方法中存在事務,false則不存在

事務的傳播及其屬性的意義:
//事務傳播屬性
@Transactional(propagation=Propagation.REQUIRED)//如果有事務,那么加入事務,沒有的話新創建一個
@Transactional(propagation=Propagation.NOT_SUPPORTED)//這個方法不開啟事務
@Transactional(propagation=Propagation.REQUIREDS_NEW)//不管是否存在事務,都創建一個新的事務,原來的掛起,新的執行完畢,繼續執行老的事務
@Transactional(propagation=Propagation.MANDATORY)//必須在一個已有的事務中執行,否則拋出異常
@Transactional(propagation=Propagation.NEVER)//不能在一個事務中執行,就是當前必須沒有事務,否則拋出異常
@Transactional(propagation=Propagation.SUPPORTS)//其他bean調用這個方法,如果在其他bean中聲明了事務,就是用事務。沒有聲明,就不用事務。
@Transactional(propagation=Propagation.NESTED)//如果一個活動的事務存在,則運行在一個嵌套的事務中,如果沒有活動的事務,則按照REQUIRED屬性執行,它使用一個單獨的事務。這個書屋擁有多個回滾的保存點,內部事務的回滾不會對外部事務造成影響,它只對DataSource TransactionManager事務管理器起效。
@Transactional(propagation=Propagation.REQUIRED,readOnly=true)//只讀,不能更新,刪除
@Transactional(propagation=Propagation.REQUIRED,timeout=30)//超時30秒

@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT)//數據庫隔離級別


事務傳播行為種類

Spring在TransactionDefinition接口中規定了7種類型的事務傳播行為,

它們規定了事務方法和事務方法發生嵌套調用時事務如何進行傳播:

說明

PROPAGATION_REQUIRED

如果當前沒有事務,就新建一個事務,如果已經存在一個事務中,加入到這個事務中。這是最常見的選擇。

PROPAGATION_SUPPORTS

支持當前事務,如果當前沒有事務,就以非事務方式執行。

PROPAGATION_MANDATORY

使用當前的事務,如果當前沒有事務,就拋出異常。

PROPAGATION_REQUIRES_NEW

新建事務,如果當前存在事務,把當前事務掛起。

PROPAGATION_NOT_SUPPORTED

以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

PROPAGATION_NEVER

以非事務方式執行,如果當前存在事務,則拋出異常。

PROPAGATION_NESTED

如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則執行與PROPAGATION_REQUIRED類似的操作。

事務的隔離等級
1. TransactionDefinition.ISOLATION_DEFAULT:這是默認值,表示使用底層數據庫的默認隔離級別。對大部分數據庫而言,通常這值就是

2. TransactionDefinition.ISOLATION_READ_COMMITTED。
TransactionDefinition.ISOLATION_READ_UNCOMMITTED:該隔離級別表示一個事務可以讀取另一個事務修改但還沒有提交的數據。該級別不能防止臟讀,不可重復讀和幻讀,因此很少使用該隔離級別。比如PostgreSQL實際上並沒有此級別。

3.TransactionDefinition.ISOLATION_READ_COMMITTED:該隔離級別表示一個事務只能讀取另一個事務已經提交的數據。該級別可以防止臟讀,這也是大多數情況下的推薦值。
TransactionDefinition.ISOLATION_REPEATABLE_READ:該隔離級別表示一個事務在整個過程中可以多次重復執行某個查詢,並且每次返回的記錄都相同。該級別可以防止臟讀和不可重復讀。

4.TransactionDefinition.ISOLATION_SERIALIZABLE:所有的事務依次逐個執行,這樣事務之間就完全不可能產生干擾,也就是說,該級別可以防止臟讀、不可重復讀以及幻讀。但是這將嚴重影響程序的性能。通常情況下也不會用到該級別。

---------------------
作者:季檢察官
來源:CSDN
原文:https://blog.csdn.net/m0_37779570/article/details/81352587
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

聲明:本文章圖片、文章均來源於網絡,版權歸原作者所有,如有侵權,請與我聯系刪除。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM