springaop事务逻辑原理_架构师:一篇文章掌握——Spring 事务管理
對大多數Java開發者來說,Spring事務管理是Spring應用中最常用的功能,使用也比較簡單。本文主要逐步介紹Spring事務管理的相關知識點及原理,作為Spring事務管理的學習總結。
一、關鍵類
事務真正的開始、提交、回滾都是通過PlatformTransactionManager這個接口來實現的,例如,我們常用的org.springframework.jdbc.datasource.DataSourceTransactionManager。
TransactionDefinition用于獲取事務的一些屬性,Isolation, Propagation,Timeout,Read-only,還定義了事務隔離級別,傳播屬性等常量。
TransactionStatus用于設置和查詢事務的狀態,如是否是新事務,是否有保存點,設置和查詢RollbackOnly等。
二、聲明式事務
所謂聲明式事務,就是通過配置的方式省去很多代碼,從而讓Spring來幫你管理事務。本質上就是配置一個Around方式的AOP,在執行方法之前,用TransactionInterceptor截取,然后調用PlatformTransactionManager的某個實現做一些事務開始前的事情,然后在方法執行后,調用PlatformTransactionManager的某個實現做commit或rollback. 如圖:
聲明式事務可以通過XML配置,也可以通過Annotation的方式來配置,還可以兩種結合。平時項目中看到比較多的是兩種結合的方式,在XML中配置數據源,事務管理器,然后AOP相關的通過@Transactional(該注解可以注在Class,Method上)來配置。(個人感覺,AOP相關的配置用XML配置挺繁瑣的,還是注解好)例如:
三、事務屬性
引用官方文檔的表格
(一)、value,在有多個事務管理器存在的情況下,用于標識使用哪個事務管理器
(二)、isolation,事務的隔離級別,默認是Isolation.DEFAULT,這個DEFAULT是和具體使用的數據庫相關的。關于隔離級別,可以參考MySQL事務學習總結
(三)、readOnly, 是否只讀,如果配置了true,但是方法里使用了update,insert語句,會報錯。對于只讀的事務,配置為true有助于提高性能。
(四)、rollbackFor, noRollbackFor. Spring的聲明式事務的默認行為是如果方法拋出RuntimeException或者Error,則事務會回滾,對于其他的checked類型的異常,不會回滾。如果想改變這種默認行為,可以通過這幾個屬性來配置。
(五)、propagation, 后面會具體講。
四、 事務的傳播機制
其他的都還好理解,后面結合例子重點介紹下PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW,PROPAGATION_NESTED三種傳播級別。
表結構和原始數據:
(一)、PROPAGATION_REQUIRED
執行完之后,test表的數據沒有任何變化。
由于MysqlTest02中的事務傳播類型是Propagation.REQUIRED,邏輯上有兩個事務,但底層是共用一個物理事務的,第二個事務的拋出RuntimeExcetion導致事務回滾,對于這種傳播類型,內層事務的回滾會導致外層事務回滾。所以數據庫中的數據沒有任何變化。
(二)、PROPAGATION_REQUIRES_NEW
同樣的代碼,唯一的區別就是第二個事務的傳播屬性改成了REQUIRES_NEW,執行結果是啥?不好意思,第二個事務執行不了。
對于REQUIRES_NEW,邏輯上有兩個事務,底層物理上也有兩個事務,由于第一個事務和第二個事務更新的是同一條記錄,對于Mysql默認的隔離級別REPEATABLE-READ來說,第一個事務會對該記錄加排他鎖,所以第二個事務就一直卡住了。
OK,我們把第二個事務的執行的SQL語句換成。
執行結果如下,可以看到只有第二個事務回滾了。
(三)、PROPAGATION_NESTED
對于這種傳播類型,物理上只有一個事務,不過可以有多個savePoint用來回滾。當然是用這種傳播類型,需要數據庫支持savePoint,使用jdbc的也是要3.0版本以上(這個不太確定)。
執行結果是如下,可以看到第一個事務和第三個事務提交成功了,第二個事務回滾了。物理上它們是在一個事務里的,只不過用到了保存點的技術。
五、其他
在寫測試代碼的時候遇到了一個關于AOP的問題,可以看到我的測試代碼,每個事務都是在一個新的class中寫的。為什么不像下面這樣寫呢?
這是因為在Spring的AOP中,test01調用test02, test02是不會被AOP截獲的,所以也不會被Spring進行事務管理。原因是Spring AOP的實現本質是通過動態代理的方式去執行真正的方法,然后在代理類里面做一些額外的事情。當通過別的類調用MysqlTest01中的test01方法時,因為使用了Spring的DI,注入的其實是一個MysqlTest01的一個代理類,而通過內部方法調用test02時,則不是。
6. Reference
Spring Framework Reference Documentation
【粉絲福利】:
《架構師資料》領取方法
關注+轉發,然后私信關鍵詞 【架構】,即可獲取。
=
總結
以上是生活随笔為你收集整理的springaop事务逻辑原理_架构师:一篇文章掌握——Spring 事务管理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 等待几秒_Java并发编程sy
- 下一篇: 异常信息配置文件已被另一个程序更改_抢先