概要:2Spring事務(wù)管理接口(隔離級(jí)別炊汹,傳播行為)篡撵、3接口介紹、4回滾原理
Spring事務(wù)的本質(zhì)其實(shí)就是數(shù)據(jù)庫對(duì)事務(wù)的支持坷澡,沒有數(shù)據(jù)庫的事務(wù)支持拼余,spring是無法提供事務(wù)功能的口予。對(duì)于純JDBC操作數(shù)據(jù)庫昔脯,想要用到事務(wù)居凶,可以按照以下步驟進(jìn)行:
1)獲取連接 Connection con = DriverManager.getConnection()
2)開啟事務(wù)con.setAutoCommit(true/false);
3)執(zhí)行CRUD????????4)提交事務(wù)/回滾事務(wù) con.commit() / con.rollback();? ? 5)關(guān)閉連接 conn.close();
1.事物的特性(ACID)
原子性坝撑、一致性累舷、隔離性傲霸、持久性
2.Spring事務(wù)管理接口:
PlatformTransactionManager:?(平臺(tái))事務(wù)管理器
TransactionDefinition:?事務(wù)定義信息(事務(wù)隔離級(jí)別宿刮、傳播行為岂嗓、超時(shí)汁展、只讀、回滾規(guī)則)
TransactionStatus:?事務(wù)運(yùn)行狀態(tài)
2.1PlatformTransactionManager:
Spring不直接管理厌殉,提供多種事務(wù)管理器食绿,委托給Hibernate或JTA等持久化機(jī)制,提供相關(guān)平臺(tái)框架事務(wù)實(shí)現(xiàn)公罕。 通過org.springframework.transaction.PlatformTransactionManager?接口器紧,為各個(gè)平臺(tái)如JDBC、Hibernate等提供事務(wù)管理器楼眷,實(shí)現(xiàn)就是各平臺(tái)的事
PlatformTransactionManager接口定義了三個(gè)方法:
不同持久層框架所對(duì)應(yīng)的接口實(shí)現(xiàn)類:
用JDBC或者iBatis(Mybatis)持久化時(shí),xml配置:
2.2 TransactionDefinition接口:
2.21并發(fā)事務(wù)帶來的問題:(事務(wù)隔離級(jí)別)
臟讀(Dirty read):事務(wù)修改,沒提交到庫罐柳,另一個(gè)事務(wù)訪問掌腰,用這數(shù)據(jù)(臟數(shù)據(jù):可能不正確)
丟失修改(Lost to modify):事務(wù)讀時(shí),另一也訪該數(shù)據(jù)张吉,第一個(gè)事務(wù)改齿梁,第二個(gè)事務(wù)也改。第一個(gè)事務(wù)丟失
不可重復(fù)讀(Unrepeatableread):事務(wù)內(nèi)多次讀同一數(shù)據(jù)肮蛹。事務(wù)沒結(jié)束勺择,另一事務(wù)也訪問該數(shù)據(jù)。第一事務(wù)中兩次讀數(shù)據(jù)之間伦忠,第二改事務(wù)省核,導(dǎo)致不一樣。?修改時(shí)
幻讀(Phantom read):與不可重復(fù)讀類似昆码。事務(wù)T1讀幾行數(shù)據(jù)气忠,事務(wù)T2插入邓深。隨后查,T1發(fā)現(xiàn)多了不存在的記錄笔刹,新增或刪除時(shí)
2.22隔離級(jí)別
TransactionDefinition.ISOLATION_DEFAULT:默認(rèn)隔離級(jí)別(用db默認(rèn)的隔離級(jí)別)芥备,Mysql 默認(rèn)REPEATABLE_READ隔離級(jí)別 ,Oracle 默認(rèn) READ_COMMITTED
1)TransactionDefinition.ISOLATION_READ_UNCOMMITTED:最低的隔離級(jí)別舌菜,允許讀取尚未提交的數(shù)據(jù)變更萌壳,可能會(huì)導(dǎo)致臟讀、幻讀或不可重復(fù)讀
2)TransactionDefinition.ISOLATION_READ_COMMITTED:允許讀取并發(fā)事務(wù)已經(jīng)提交的數(shù)據(jù)日月,阻止臟讀袱瓮,但幻讀或不可重復(fù)讀仍有可能
3)TransactionDefinition.ISOLATION_REPEATABLE_READ:對(duì)同一字段的多次讀取結(jié)果都是一致的,除非數(shù)據(jù)是被本身事務(wù)自己所修改爱咬,可以阻止臟讀和不可重復(fù)讀尺借,但幻讀仍有可能發(fā)生。
4)TransactionDefinition.ISOLATION_SERIALIZABLE:最高隔離級(jí)別精拟,防止臟讀燎斩、不可重復(fù)讀以及幻讀。
2.23事務(wù)傳播行為(解決方法間調(diào)用事務(wù)問題)
事務(wù)方法被另一個(gè)事務(wù)方法調(diào)用時(shí)蜂绎,必須如何傳播栅表。如:方法可能繼續(xù)現(xiàn)有事務(wù)中運(yùn)行,也可開啟新事務(wù)师枣,并在自的事務(wù)中運(yùn)行怪瓶。TransactionDefinition定義中傳播行為常量:
1)TransactionDefinition.PROPAGATION_REQUIRED:如當(dāng)前存在事務(wù),則加入該事務(wù)践美;沒有創(chuàng)建新事務(wù)洗贰。
2)TransactionDefinition.PROPAGATION_SUPPORTS:如當(dāng)前存在事務(wù),則加入該事務(wù)陨倡;沒有敛滋,以非事務(wù)方式繼續(xù)運(yùn)行
3)TransactionDefinition.PROPAGATION_MANDATORY:如當(dāng)前存在事務(wù),則加入該事務(wù)玫膀;沒有則拋異常
? ??不支持當(dāng)前事務(wù)的情況:
TransactionDefinition.PROPAGATION_REQUIRES_NEW:創(chuàng)建新事務(wù)矛缨,當(dāng)前存在事務(wù),把當(dāng)前事務(wù)掛起
TransactionDefinition.PROPAGATION_NOT_SUPPORTED:非事務(wù)方式運(yùn)行帖旨,當(dāng)前存在事務(wù)箕昭,把當(dāng)前事務(wù)掛起
TransactionDefinition.PROPAGATION_NEVER:非事務(wù)方式運(yùn)行,當(dāng)前存在事務(wù)解阅,拋異常
? ??其他情況:
TransactionDefinition.PROPAGATION_NESTED:如果當(dāng)前存在事務(wù)落竹,則創(chuàng)建一個(gè)事務(wù)作為當(dāng)前事務(wù)的嵌套事務(wù)來運(yùn)行;如果當(dāng)前沒有事務(wù)货抄,則該取值等價(jià)于TransactionDefinition.PROPAGATION_REQUIRED述召。
這里需要指出的是朱转,前面的六種事務(wù)傳播行為是 Spring 從 EJB 中引入的,他們共享相同的概念积暖。而PROPAGATION_NESTED是 Spring 所特有的藤为。以 PROPAGATION_NESTED 啟動(dòng)的事務(wù)內(nèi)嵌于外部事務(wù)中(如果存在外部事務(wù)的話),此時(shí)夺刑,內(nèi)嵌事務(wù)并不是一個(gè)獨(dú)立的事務(wù)缅疟,它依賴于外部事務(wù)的存在,只有通過外部的事務(wù)提交遍愿,才能引起內(nèi)部事務(wù)的提交存淫,嵌套的子事務(wù)不能單獨(dú)提交。如果熟悉 JDBC 中的保存點(diǎn)(SavePoint)的概念沼填,那嵌套事務(wù)就很容易理解了桅咆,其實(shí)嵌套的子事務(wù)就是保存點(diǎn)的一個(gè)應(yīng)用,一個(gè)事務(wù)中可以包括多個(gè)保存點(diǎn)坞笙,每一個(gè)嵌套子事務(wù)岩饼。另外,外部事務(wù)的回滾也會(huì)導(dǎo)致嵌套子事務(wù)的回滾羞海。
2.24事務(wù)超時(shí)屬性(一個(gè)事務(wù)允許執(zhí)行的最長(zhǎng)時(shí)間)
超時(shí)沒完成忌愚,自動(dòng)回滾。int表示時(shí)間却邓,單位是秒
2.25事務(wù)只讀屬性(對(duì)事物資源是否執(zhí)行只讀操作)
以提高事務(wù)處理性能。在 TransactionDefinition 中以 boolean 表示
2.26回滾規(guī)則(定義事務(wù)回滾規(guī)則)
定義哪些異常會(huì)回滾院水、哪些不會(huì)腊徙。默認(rèn),運(yùn)行期異常時(shí)會(huì)回滾檬某,檢查型異常不回滾(與EJB回滾行為一致)
但可聲明事務(wù)特定檢查型異常時(shí)撬腾,像運(yùn)行異常那樣回滾。還可聲明運(yùn)行異常不回滾
3.TransactionStatus接口介紹
記錄事務(wù)狀態(tài) 定義了一組方法,用來獲取或判斷事務(wù)相應(yīng)狀態(tài)信息
PlatformTransactionManager.getTransaction(…) 方法返回TransactionStatus 對(duì)象恢恼。
返回TransactionStatus 對(duì)象可能代表新的或已經(jīng)存在事務(wù)(如當(dāng)前調(diào)用堆棧有符合條件事務(wù))民傻。
4、Spring事務(wù)回滾底層實(shí)現(xiàn)
用TransactionInterceptor方法攔截器實(shí)現(xiàn)事務(wù)經(jīng)過以下步驟實(shí)現(xiàn)回滾
1)獲取事務(wù)屬性(注解@Transactional的屬性)
2)獲取事務(wù)管理器PlatformTransactionManager
3)獲取需要事務(wù)的方法名和事務(wù)信息
4)創(chuàng)建事務(wù)场斑、獲取事務(wù)
4)目標(biāo)方法執(zhí)行
5)事務(wù)回滾(如果是嵌套回滾則回滾到保存點(diǎn))
參考:https://zhuanlan.zhihu.com/p/149409015
另加2:
a方法內(nèi)調(diào)b方法漓踢,然后a方法拋出異常導(dǎo)致事務(wù)回滾,如何讓b方法執(zhí)行結(jié)果不回滾漏隐?
B方法事務(wù)級(jí)別require new喧半,不要寫在同一個(gè)類aop切不到,想同一個(gè)類調(diào)用青责,自己去applicationcontex 拿bean
https://my.oschina.net/xiaolyuh/blog/3109049