Spring 事務(wù)的隔離級(jí)別和傳播行為
try catch 對(duì) Spring 事務(wù)的影響
一、Spring 事務(wù)管理的兩種方式
1??編程式事務(wù)侵入到了業(yè)務(wù)代碼里面,但是提供了更加詳細(xì)的事務(wù)管理。編程式事務(wù)使用 TransactionTemplate 或者直接使用底層的 PlatformTransactionManager。對(duì)于編程式事務(wù)管理,Spring 推薦使用 TransactionTemplate。
2??聲明式事務(wù)基于 AOP,既能管理事務(wù),又不影響業(yè)務(wù)代碼。本質(zhì)是對(duì)方法前后進(jìn)行攔截,然后在目標(biāo)方法開始之前創(chuàng)建或者加入一個(gè)事務(wù),在目標(biāo)方法執(zhí)行完后根據(jù)執(zhí)行情況提交或者回滾事務(wù)。最大的優(yōu)點(diǎn)就是不需要通過編程的方式管理事務(wù),這樣就不需要在業(yè)務(wù)邏輯代碼中摻雜事務(wù)管理的代碼,只需在配置文件中做相關(guān)的事務(wù)規(guī)則聲明(或基于 @Transactional 的方式),便可以將事務(wù)規(guī)則應(yīng)用到業(yè)務(wù)邏輯中。
二、對(duì)比說明
顯然聲明式事務(wù)管理要優(yōu)于編程式事務(wù)管理,這正是 Spring 倡導(dǎo)的非侵入式的開發(fā)方式。聲明式事務(wù)管理使業(yè)務(wù)代碼不受污染,一個(gè) POJO,只要加上注解就可以獲得完全的事務(wù)支持。和編程式事務(wù)相比,聲明式事務(wù)唯一不足的地方,它的最細(xì)粒度只能作用到方法級(jí)別,無(wú)法做到像編程式事務(wù)那樣可以作用到代碼塊級(jí)別。但是即便有這樣的需求,也存在很多變通的方法,比如,可以將需要進(jìn)行事務(wù)管理的代碼塊獨(dú)立為方法等等。
三、聲明式事務(wù)管理的兩種實(shí)現(xiàn)
聲明式事務(wù)管理有兩種常用的方式,一種是基于 tx 和 aop 名字空間的 xml 配置文件,另一種就是基于 @Transactional。顯然基于注解的方式更簡(jiǎn)單易用,更清爽。
四、@Transactional 一般可以作用在類或者方法上
1??作用于類:當(dāng)把 @Transactional 放在類上時(shí),表示該類所有的 public 方法都配置相同的事務(wù)屬性信息。
2??作用于方法:當(dāng)類配置了@Transactional,方法也配置了 @Transactional,方法的事務(wù)會(huì)覆蓋類的事務(wù)配置信息。
五、Spring 事務(wù)的基本原理
Spring 事務(wù)的本質(zhì)其實(shí)就是數(shù)據(jù)庫(kù)對(duì)事務(wù)的支持,沒有數(shù)據(jù)庫(kù)的事務(wù)支持,Spring 是無(wú)法提供事務(wù)功能的。對(duì)于純 JDBC 操作數(shù)據(jù)庫(kù),想要用到事務(wù),可以按照以下步驟進(jìn)行:
- 獲取連接 Connection con = DriverManager.getConnection();
- 開啟事務(wù) con.setAutoCommit(true/false);
- 執(zhí)行 CRUD;
- 提交事務(wù)/回滾事務(wù) con.commit()/con.rollback();
- 關(guān)閉連接 con.close()。
使用 Spring 的事務(wù)管理功能后,開發(fā)者可以不再寫步驟 2 和 4 的代碼,而是由 Spirng 自動(dòng)完成。Spring 是如何在 CRUD 前后開啟/關(guān)閉事務(wù)的?解決這個(gè)問題,也就可以從整體上理解 Spring 的事務(wù)管理實(shí)現(xiàn)原理了。下面簡(jiǎn)單地介紹下,注解方式為例子:
- 配置文件開啟注解驅(qū)動(dòng),在相關(guān)的類和方法上通過 @Transactional 標(biāo)識(shí)。
- Spring 在啟動(dòng)的時(shí)候會(huì)去解析生成相關(guān)的 bean,這時(shí)候會(huì)查看擁有相關(guān)注解的類和方法,并且為這些類和方法生成代理,并根據(jù) @Transactional 的相關(guān)參數(shù)進(jìn)行相關(guān)配置注入,這樣就在代理中把相關(guān)的事務(wù)實(shí)現(xiàn)了(開啟正常提交事務(wù),異常回滾事務(wù))。
- 真正的數(shù)據(jù)庫(kù)層的事務(wù)提交和回滾是通過 redo log/binlog 實(shí)現(xiàn)的。
六、原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)
事務(wù)最經(jīng)典的例子就是轉(zhuǎn)賬了。假如小黑要給小白轉(zhuǎn)賬 100 元,這個(gè)轉(zhuǎn)賬會(huì)涉及到兩個(gè)關(guān)鍵操作就是:將小黑的余額減少 100 元,將小白的余額增加 100 元。萬(wàn)一在這兩個(gè)操作之間突然出現(xiàn)錯(cuò)誤(如銀行系統(tǒng)崩潰等),導(dǎo)致小黑余額減少而小白的余額沒有增加,這樣就不對(duì)了。事務(wù)就是保證這兩個(gè)關(guān)鍵操作要么都成功,要么都要失敗。1??原子性。一個(gè)事務(wù)是一個(gè)不可分割的工作單位,事務(wù)中包括的操作要么都做,要么都不做。
2??一致性。事務(wù)必須是使數(shù)據(jù)庫(kù)從一個(gè)一致性狀態(tài)變到另一個(gè)一致性狀態(tài)。一致性與原子性是密切相關(guān)的。
3??隔離性。一個(gè)事務(wù)的執(zhí)行不能被其他事務(wù)干擾。即一個(gè)事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對(duì)并發(fā)的其他事務(wù)是隔離的,并發(fā)執(zhí)行的各個(gè)事務(wù)之間不能互相干擾。
4??持久性。持久性也稱永久性(permanence),指一個(gè)事務(wù)一旦提交,它對(duì)數(shù)據(jù)庫(kù)中數(shù)據(jù)的改變就應(yīng)該是永久性的。接下來(lái)的其他操作或故障不應(yīng)該對(duì)其有任何影響。