個(gè)人網(wǎng)站建站系統(tǒng)百度搜索排名
文章目錄
- 數(shù)據(jù)庫(kù)事務(wù)
- 事務(wù)特性(ACID)
- 原子性(Atomicity)
- 一致性(Consistency)
- 隔離性(Isolation)
- 持久性(Durability)
- 隔離級(jí)別
- Read Uncommitted(讀未提交)
- Read Committed(讀已提交)
- Repeatable Read(可重復(fù)讀)
- Serializable(可串行化)
- Spring事務(wù)機(jī)制
- 實(shí)現(xiàn)方式
- 提交方式
- 事務(wù)隔離級(jí)別
- 事務(wù)傳播行為
- 事務(wù)回滾規(guī)則
- 事務(wù)常用配置
- 失效場(chǎng)景
數(shù)據(jù)庫(kù)事務(wù)
什么叫事務(wù)?
事務(wù)是一系列對(duì)系統(tǒng)中數(shù)據(jù)進(jìn)行訪問(wèn)與更新的操作組成的一個(gè)程序邏輯單元。即不可分割的許多基礎(chǔ)數(shù)據(jù)庫(kù)操作。
事務(wù)特性(ACID)
原子性(Atomicity)
原子性是指一個(gè)事務(wù)(事務(wù)是最小的執(zhí)行單位)是一個(gè)不可分割的工作單元,其中的操作要么都做,要么都不做。如果事務(wù)中一個(gè)sql語(yǔ)句執(zhí)行失敗,則已執(zhí)行的語(yǔ)句也必須回滾,數(shù)據(jù)庫(kù)退回到事務(wù)前的狀態(tài)。
實(shí)現(xiàn)原理
① 回滾日志(undo log)
InnoDB實(shí)現(xiàn)回滾靠的是undo log。當(dāng)事務(wù)對(duì)數(shù)據(jù)庫(kù)進(jìn)行修改時(shí),InnoDB會(huì)生成對(duì)應(yīng)的undo log。如果事務(wù)執(zhí)行失敗或調(diào)用了rollback,導(dǎo)致事務(wù)需要回滾,便可利用undo log中的信息將數(shù)據(jù)回滾到修改前。
- 對(duì)于每個(gè)
insert
,回滾時(shí)會(huì)執(zhí)行delete
- 對(duì)于每個(gè)
delete
,回滾時(shí)會(huì)執(zhí)行insert
- 對(duì)于每個(gè)
update
,回滾時(shí)會(huì)執(zhí)行一個(gè)相反的update
,把數(shù)據(jù)改回去
一致性(Consistency)
一致性是指事務(wù)執(zhí)行結(jié)束后,數(shù)據(jù)庫(kù)的完整性約束沒(méi)有被破壞,事務(wù)執(zhí)行的前后都是合法的數(shù)據(jù)狀態(tài)。
數(shù)據(jù)庫(kù)的完整性約束包括但不限于:實(shí)體完整性(如行的主鍵存在且唯一)、列完整性(如字段的類型、大小、長(zhǎng)度要符合要求)、外鍵約束、用戶自定義完整性(如轉(zhuǎn)賬前后,兩個(gè)賬戶余額的和應(yīng)該不變)。假如A賬戶給B賬戶轉(zhuǎn)10塊錢,不管成功與否,A和B的總金額是不變的。
實(shí)現(xiàn)原理
一致性是事務(wù)追求的最終目標(biāo)。前面提到的原子性、持久性和隔離性,都是為了保證數(shù)據(jù)庫(kù)狀態(tài)的一致性。此外,除了數(shù)據(jù)庫(kù)層面的保障,一致性的實(shí)現(xiàn)也需要應(yīng)用層面進(jìn)行保障。實(shí)現(xiàn)一致性的措施包括:
① 保證原子性、持久性和隔離性。如果這些特性無(wú)法保證,事務(wù)的一致性也無(wú)法保證
② 數(shù)據(jù)庫(kù)本身提供保障。如不允許向整型列插入字符串值、字符串長(zhǎng)度不能超過(guò)列的限制等
③ 應(yīng)用層面進(jìn)行保障。如轉(zhuǎn)賬操作只扣除轉(zhuǎn)賬者余額,而未增加接收者余額
隔離性(Isolation)
**隔離性是指事務(wù)內(nèi)部的操作與其它事務(wù)是隔離的,并發(fā)執(zhí)行的各個(gè)事務(wù)之間不能互相干擾。**嚴(yán)格的隔離性,對(duì)應(yīng)了事務(wù)隔離級(jí)別中的Serializable (可串行化),但實(shí)際應(yīng)用中出于性能方面的考慮很少會(huì)使用可串行化。
實(shí)現(xiàn)原理
隔離性追求的是并發(fā)情形下事務(wù)之間互不干擾。主要分為兩個(gè)方面:
① 加鎖機(jī)制保證隔離性:(一個(gè)事務(wù))寫操作對(duì)(另一個(gè)事務(wù))寫操作的影響
事務(wù)在修改數(shù)據(jù)之前,需要先獲得相應(yīng)的鎖;獲得鎖之后,事務(wù)便可以修改數(shù)據(jù);該事務(wù)操作期間,這部分?jǐn)?shù)據(jù)是鎖定的,其它事務(wù)如果需要修改數(shù)據(jù),需要等待當(dāng)前事務(wù)提交或回滾后釋放鎖。
② MVCC(多版本并發(fā)控制)保證隔離性:(一個(gè)事務(wù))寫操作對(duì)(另一個(gè)事務(wù))讀操作的影響
MVCC全稱Multi-Version Concurrency Control,即多版本的并發(fā)控制協(xié)議。最大優(yōu)點(diǎn)是讀不加鎖,因此讀寫不沖突,并發(fā)性能好。InnoDB的MVCC實(shí)現(xiàn)了多個(gè)版本的數(shù)據(jù)可共存,主要基于以下技術(shù)及數(shù)據(jù)結(jié)構(gòu):
- 隱藏列:在Innodb引擎中每行數(shù)據(jù)都會(huì)有兩個(gè)隱藏列(實(shí)際是三個(gè)列)
- 隱藏id(
id
,如果建表時(shí)沒(méi)有顯式指定,則會(huì)生成這個(gè)隱藏id作為主鍵,實(shí)際和mvcc沒(méi)有關(guān)系) - 創(chuàng)建版本號(hào)(
data_trx_id
,事務(wù)id):用來(lái)標(biāo)識(shí)最近對(duì)本行記錄做修改的事務(wù) id - 回滾指針(
data_roll_pointer
,指向undo log的指針)
- 隱藏id(
- 基于undo log版本鏈:每條undo log也會(huì)指向更早版本的undo log,從而形成一條版本鏈
- ReadView:**通過(guò)隱藏列和版本鏈可以將數(shù)據(jù)恢復(fù)到指定版本,但具體要恢復(fù)到哪個(gè)版本,則需要根據(jù)ReadView來(lái)確定。**當(dāng)進(jìn)行查詢操作時(shí),事務(wù)會(huì)生成一個(gè)ReadView(是一個(gè)事務(wù)快照),準(zhǔn)確來(lái)說(shuō)是當(dāng)前時(shí)間點(diǎn)系統(tǒng)內(nèi)活躍的事務(wù)列表,也就是說(shuō)系統(tǒng)內(nèi)所有未提交的事務(wù),都會(huì)記錄在這個(gè)Readview內(nèi),事務(wù)就根據(jù)它來(lái)判斷哪些數(shù)據(jù)是可見(jiàn)的,哪些是不可見(jiàn)的。在每一條 SQL 開(kāi)始的時(shí)候被創(chuàng)建,有幾個(gè)重要屬性:
- trx_ids: 當(dāng)前系統(tǒng)活躍(未提交)事務(wù)版本號(hào)集合
- low_limit_id: 創(chuàng)建當(dāng)前 read view 時(shí)“當(dāng)前系統(tǒng)最大事務(wù)版本號(hào)+1”
- up_limit_id: 創(chuàng)建當(dāng)前read view 時(shí)“系統(tǒng)正處于活躍事務(wù)最小版本號(hào)”
- creator_trx_id: 創(chuàng)建當(dāng)前read view的事務(wù)版本號(hào)
MVCC查詢流程
現(xiàn)在開(kāi)始查詢,一個(gè) select 過(guò)來(lái)了,找到了一行數(shù)據(jù)。
- data_trx_id < up_limit_id:說(shuō)明數(shù)據(jù)在當(dāng)前事務(wù)之前就存在了,顯示
- data_trx_id >= low_limit_id:說(shuō)明該數(shù)據(jù)是在當(dāng)前read view 創(chuàng)建后才產(chǎn)生的,數(shù)據(jù)不顯示。不顯示怎么辦,根據(jù) data_roll_pointer 從 undo log 中找到歷史版本,找不到就空
- up_limit_id < data_trx_id < low_limit_id:就要看隔離級(jí)別了
MVCC應(yīng)用場(chǎng)景
在Mysql的InnoDB引擎中,只有已提交讀和可重復(fù)讀這兩種隔離級(jí)別的事務(wù)采用了MVCC機(jī)制:
- 已提交讀(READ COMMITTD):事務(wù)中的每次讀操作都會(huì)生成一個(gè)新的ReadView,也就是說(shuō)如果這期間某個(gè)事務(wù)提交了,那么它就會(huì)從ReadView中移除。這樣確保事務(wù)每次讀操作都能讀到相對(duì)比較新的數(shù)據(jù)
- 可重復(fù)讀(REPEATABLE READ):事務(wù)只有在第一次進(jìn)行讀操作時(shí)才會(huì)生成一個(gè)ReadView,后續(xù)的讀操作都會(huì)重復(fù)使用這個(gè)ReadView。也就是說(shuō)如果在此期間有其他事務(wù)提交了,那么對(duì)于可重復(fù)讀來(lái)說(shuō)也是不可見(jiàn)的,因?yàn)閷?duì)它來(lái)說(shuō),事務(wù)活躍狀態(tài)在第一次進(jìn)行讀操作時(shí)就已經(jīng)確定下來(lái),后面不會(huì)修改了
持久性(Durability)
持久性是指事務(wù)一旦提交,它對(duì)數(shù)據(jù)庫(kù)的改變就應(yīng)該是永久性的,即使數(shù)據(jù)庫(kù)發(fā)生故障也不受影響。
實(shí)現(xiàn)原理
① redo log
當(dāng)數(shù)據(jù)修改時(shí),除了修改Buffer Pool中的數(shù)據(jù),還會(huì)在redo log記錄這次操作;當(dāng)事務(wù)提交時(shí),會(huì)調(diào)用fsync接口對(duì)redo log進(jìn)行刷盤(刷臟頁(yè))。如果MySQL宕機(jī),重啟時(shí)可以讀取redo log中的數(shù)據(jù),對(duì)數(shù)據(jù)庫(kù)進(jìn)行恢復(fù)。redo log采用的是WAL(Write-ahead logging,預(yù)寫式日志),所有修改先寫入日志,再更新到Buffer Pool,保證了數(shù)據(jù)不會(huì)因MySQL宕機(jī)而丟失,從而滿足了持久性要求。
為什么redo log寫入磁盤比直接將Buffer Pool中修改數(shù)據(jù)寫入磁盤(刷臟)快?
- 刷臟是隨機(jī)I/O,因?yàn)槊看涡薷牡臄?shù)據(jù)位置隨機(jī),但寫redo log是追加操作,屬于順序I/O
- 刷臟是以數(shù)據(jù)頁(yè)(Page)為單位的,MySQL默認(rèn)頁(yè)大小是16KB,一個(gè)Page上一個(gè)小修改都要整頁(yè)寫入;而redo log中只包含真正需要寫入的部分,無(wú)效I/O大大減少
隔離級(jí)別
事務(wù)并發(fā)問(wèn)題
在事務(wù)的并發(fā)操作中,不做隔離操作則可能會(huì)出現(xiàn) 臟讀、不可重復(fù)讀、幻讀 問(wèn)題:
-
臟讀:指一個(gè)事務(wù)讀取到了另一個(gè)未提交事務(wù)修改過(guò)的數(shù)據(jù)
事務(wù)A中讀到了事務(wù)B中未提交的更新數(shù)據(jù)內(nèi)容,然后B回滾操作,那么A讀取到的數(shù)據(jù)是臟數(shù)據(jù)。
-
不可重復(fù)讀:同一個(gè)事務(wù)內(nèi),前后多次讀取,讀取到的數(shù)據(jù)內(nèi)容不一致
事務(wù)A讀到事務(wù)B已經(jīng)提交后的數(shù)據(jù),即事務(wù)A多次讀取同一數(shù)據(jù)時(shí),返回結(jié)果不一致。
-
幻讀:指一個(gè)事務(wù)先根據(jù)某些搜索條件查詢出一些記錄,在該事務(wù)未提交時(shí),另一個(gè)事務(wù)寫入了一些符合那些搜索條件的記錄(如insert、delete、update),再次查詢出的結(jié)果則出現(xiàn)不一致
事物A執(zhí)行select后,事物B增或刪了一條數(shù)據(jù),事務(wù)A再執(zhí)行同一條SQL后發(fā)現(xiàn)多或少了一條數(shù)據(jù)。
-
第一類丟失更新: A事務(wù)撤銷事務(wù)時(shí),覆蓋了B事務(wù)提交的事務(wù)(現(xiàn)代關(guān)系型數(shù)據(jù)庫(kù)中已經(jīng)不會(huì)發(fā)生)
-
第二類丟失更新: A事務(wù)提交事務(wù)時(shí),覆蓋了B事務(wù)提交的事務(wù)(是不可重復(fù)讀的特殊情況)
小結(jié):不可重復(fù)讀的和幻讀很容易混淆,不可重復(fù)讀側(cè)重于修改,幻讀側(cè)重于新增或刪除。解決不可重復(fù)讀的問(wèn)題只需鎖住滿足條件的行,解決幻讀需要鎖表。查看 mysql
事務(wù)隔離級(jí)別:show variables like 'tx_iso%';
。
InnoDB存儲(chǔ)引擎下的四種隔離級(jí)別發(fā)生問(wèn)題的可能性如下:
隔離級(jí)別 | 第一類丟失更新 | 第二類丟失更新 | 臟讀 | 不可重復(fù)讀 | 幻讀 |
---|---|---|---|---|---|
Read Uncommitted(讀未提交) | 不可能 | 可能 | 可能 | 可能 | 可能 |
Read Committed(讀已提交) | 不可能 | 可能 | 不可能 | 可能 | 可能 |
Repeatable Read(可重復(fù)讀) | 不可能 | 不可能 | 不可能 | 不可能 | 可能 |
Serializable(串行化) | 不可能 | 不可能 | 不可能 | 不可能 | 不可能 |
Read Uncommitted(讀未提交)
只限制了兩個(gè)數(shù)據(jù)不能同時(shí)修改,但即使事務(wù)未提交也會(huì)讀取到其它事務(wù)未提交的內(nèi)容(可能會(huì)被回滾)。會(huì)有臟讀、重復(fù)讀、幻讀的問(wèn)題,讀取未提交的數(shù)據(jù),也被稱之為臟讀(Dirty Read)。
特點(diǎn):最低級(jí)別,任何情況都無(wú)法保證
數(shù)據(jù)庫(kù)鎖情況
- 讀取數(shù)據(jù):未加鎖,每次都讀到最新數(shù)據(jù),性能最好
- 寫入數(shù)據(jù):只對(duì)數(shù)據(jù)增加行級(jí)共享鎖,寫完釋放
Read Committed(讀已提交)
當(dāng)前事務(wù)只能讀取到其它事務(wù)已提交的數(shù)據(jù)。因同一事務(wù)的其它實(shí)例在該實(shí)例處理期間可能會(huì)有新的commit,所以同一select可能返回不同結(jié)果,這就是所謂的不可重復(fù)讀(Nonrepeatable Read)。該隔離級(jí)別解決了臟讀問(wèn)題,但還是會(huì)存在重復(fù)讀、幻讀問(wèn)題。
特點(diǎn):避免臟讀
臟讀解決方案:基于樂(lè)觀鎖理論的MVCC(多版本并發(fā)控)實(shí)現(xiàn)
數(shù)據(jù)庫(kù)鎖情況
- 讀取數(shù)據(jù):加行級(jí)共享鎖(讀到時(shí)才加鎖),讀完后立即釋放
- 寫入數(shù)據(jù):在更新時(shí)的瞬間對(duì)其加行級(jí)排它鎖,直到事務(wù)結(jié)束才釋放
Repeatable Read(可重復(fù)讀)
限制了讀取數(shù)據(jù)時(shí)不可以進(jìn)行修改,所以解決了不能重復(fù)讀的問(wèn)題。但是讀取范圍數(shù)據(jù)的時(shí)候,是可以插入或刪除數(shù)據(jù),所以還會(huì)存在**幻讀(Phantom Read)**問(wèn)題。
幻讀 是戶讀取某一范圍的數(shù)據(jù)行時(shí),另一個(gè)事務(wù)又在該范圍內(nèi)插入了新行,當(dāng)該用戶再讀取該范圍的數(shù)據(jù)行時(shí),會(huì)發(fā)現(xiàn)有新的“幻影” 行。
特點(diǎn):避免臟讀、不可重復(fù)讀。MySQL默認(rèn)事務(wù)隔離級(jí)別
不可重復(fù)讀解決方案:基于樂(lè)觀鎖理論的MVCC(多版本并發(fā)控)實(shí)現(xiàn)
數(shù)據(jù)庫(kù)鎖情況
- 讀取數(shù)據(jù):開(kāi)始讀取的瞬間對(duì)其增加行級(jí)共享鎖,直到事務(wù)結(jié)束才釋放
- 寫入數(shù)據(jù):開(kāi)始更新的瞬間對(duì)其增加行級(jí)排他鎖,直到事務(wù)結(jié)束才釋放
Serializable(可串行化)
所有事務(wù)都是進(jìn)行串行化順序執(zhí)行的??梢员苊?strong>臟讀、不可重復(fù)讀與幻讀所有并發(fā)問(wèn)題。但該事務(wù)隔離級(jí)別下,事務(wù)執(zhí)行很耗性能。
特點(diǎn):避免臟讀、不可重復(fù)讀、幻讀
數(shù)據(jù)庫(kù)鎖情況
- 讀取數(shù)據(jù):先對(duì)其加表級(jí)共享鎖 ,直到事務(wù)結(jié)束才釋放
- 寫入數(shù)據(jù):先對(duì)其加表級(jí)排他鎖 ,直到事務(wù)結(jié)束才釋放
Spring事務(wù)機(jī)制
實(shí)現(xiàn)方式
在Spring中事務(wù)有兩種實(shí)現(xiàn)方式:
- 編程式事務(wù)管理: 編程式事務(wù)管理使用
TransactionTemplate
或直接使用底層的PlatformTransactionManager
- 聲明式事務(wù)管理: 建立在
AOP
之上的。其本質(zhì)是對(duì)方法前后進(jìn)行攔截,然后在目標(biāo)方法開(kāi)始之前創(chuàng)建或者加入一個(gè)事務(wù),在執(zhí)行完目標(biāo)方法之后根據(jù)執(zhí)行情況提交或者回滾事務(wù)。聲明式事務(wù)管理不需要入侵代碼,通過(guò)@Transactional
就可以進(jìn)行事務(wù)操作,更快捷而且簡(jiǎn)單
提交方式
默認(rèn)情況下,數(shù)據(jù)庫(kù)處于自動(dòng)提交模式。每一條語(yǔ)句處于一個(gè)單獨(dú)的事務(wù)中,在這條語(yǔ)句執(zhí)行完畢時(shí),如果執(zhí)行成功則隱式的提交事務(wù),如果執(zhí)行失敗則隱式的回滾事務(wù)。
對(duì)于正常的事務(wù)管理,是一組相關(guān)的操作處于一個(gè)事務(wù)之中,因此必須關(guān)閉數(shù)據(jù)庫(kù)的自動(dòng)提交模式。不過(guò),這個(gè)我們不用擔(dān)心,Spring會(huì)將底層連接的自動(dòng)提交特性設(shè)置為false。也就是在使用Spring進(jìn)行事物管理的時(shí)候,Spring會(huì)將是否自動(dòng)提交設(shè)置為false,等價(jià)于JDBC中的 connection.setAutoCommit(false);
,在執(zhí)行完之后在進(jìn)行提交,connection.commit();
。
事務(wù)隔離級(jí)別
隔離級(jí)別是指若干個(gè)并發(fā)的事務(wù)之間的隔離程度。
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void addGoods(){......
}
枚舉類Isolation中定義了五種隔離級(jí)別:
DEFAULT
:默認(rèn)值。表示使用底層數(shù)據(jù)庫(kù)的默認(rèn)隔離級(jí)別。對(duì)大部分?jǐn)?shù)據(jù)庫(kù),通常這值就是READ_COMMITTEDREAD_UNCOMMITTED
:該隔離級(jí)別表示一個(gè)事務(wù)可以讀取另一個(gè)事務(wù)修改但還沒(méi)有提交的數(shù)據(jù)。該級(jí)別不能防止臟讀,不可重復(fù)讀和幻讀,因此很少使用該隔離級(jí)別READ_COMMITTED
:該隔離級(jí)別表示一個(gè)事務(wù)只能讀取另一個(gè)事務(wù)已經(jīng)提交的數(shù)據(jù)。該級(jí)別可以防止臟讀,這也是大多數(shù)情況下的推薦值REPEATABLE_READ
:該隔離級(jí)別表示一個(gè)事務(wù)在整個(gè)過(guò)程中可以多次重復(fù)執(zhí)行某個(gè)查詢,并且每次返回的記錄都相同。該級(jí)別可以防止臟讀和不可重復(fù)讀SERIALIZABLE
:所有的事務(wù)依次逐個(gè)執(zhí)行,這樣事務(wù)之間就完全不可能產(chǎn)生干擾,也就是說(shuō),該級(jí)別可以防止臟讀、不可重復(fù)讀以及幻讀。但是這將嚴(yán)重影響程序的性能。通常情況下也不會(huì)用到該級(jí)別
事務(wù)傳播行為
事務(wù)的傳播性一般用在事務(wù)嵌套的場(chǎng)景,如一個(gè)事務(wù)方法里面調(diào)用了另外一個(gè)事務(wù)方法,那兩個(gè)方法是各自作為獨(dú)立的方法提交還是內(nèi)層事務(wù)合并到外層事務(wù)一起提交,這就需要事務(wù)傳播機(jī)制配置來(lái)確定怎么樣執(zhí)行。
@Transactional(propagation=Propagation.REQUIRED)
public void addGoods(){......
}
枚舉類Propagation中定義了七種事務(wù)傳播機(jī)制如下:
REQUIRED
(required,要求,Spring默認(rèn)):當(dāng)前存在事務(wù),則加入該事務(wù);當(dāng)前沒(méi)有事務(wù),則創(chuàng)建一個(gè)新的事務(wù)REQUIRES_NEW
(requires_new,要求新的):創(chuàng)建一個(gè)新事務(wù),如果存在當(dāng)前事務(wù),則掛起該事務(wù)SUPPORTS
(supports,支持):如果當(dāng)前存在事務(wù),則加入當(dāng)前事務(wù);如果當(dāng)前沒(méi)有事務(wù),就以非事務(wù)方法執(zhí)行NOT_SUPPORTED
(not_supported,不支持):始終以非事務(wù)方式執(zhí)行,如果當(dāng)前存在事務(wù),則掛起當(dāng)前事務(wù)NEVER
(never,都不):不使用事務(wù),如果當(dāng)前事務(wù)存在,則拋出異常MANDATORY
(mandatory,強(qiáng)制):如果當(dāng)前存在事務(wù),則加入當(dāng)前事務(wù);如果當(dāng)前事務(wù)不存在,則拋出異常NESTED
(nested,嵌套)如果當(dāng)前事務(wù)存在,則在嵌套事務(wù)中執(zhí)行,否則REQUIRED的操作一樣(開(kāi)啟一個(gè)事務(wù))
事務(wù)回滾規(guī)則
指示Spring事務(wù)管理器回滾一個(gè)事務(wù)的推薦方法是在當(dāng)前事務(wù)的上下文內(nèi)拋出異常。Spring事務(wù)管理器會(huì)捕捉任何未處理的異常,然后依據(jù)規(guī)則決定是否回滾拋出異常的事務(wù)。
默認(rèn)配置下,Spring只有在拋出的異常為運(yùn)行時(shí)unchecked異常時(shí)才回滾該事務(wù),也就是拋出的異常為RuntimeException的子類(Errors也會(huì)導(dǎo)致事務(wù)回滾),而拋出checked異常則不會(huì)導(dǎo)致事務(wù)回滾。
可以明確的配置在拋出那些異常時(shí)回滾事務(wù),包括checked異常。也可以明確定義那些異常拋出時(shí)不回滾事務(wù)。
事務(wù)常用配置
-
readOnly
該屬性用于設(shè)置當(dāng)前事務(wù)是否為只讀事務(wù),設(shè)置為true表示只讀,false則表示可讀寫,默認(rèn)值為false。例如:@Transactional(readOnly=true)
-
rollbackFor
該屬性用于設(shè)置需要進(jìn)行回滾的異常類數(shù)組,當(dāng)方法中拋出指定異常數(shù)組中的異常時(shí),則進(jìn)行事務(wù)回滾。例如:指定單一異常類:@Transactional(rollbackFor=RuntimeException.class)指定多個(gè)異常類:@Transactional(rollbackFor={RuntimeException.class, Exception.class})
-
rollbackForClassName
該屬性用于設(shè)置需要進(jìn)行回滾的異常類名稱數(shù)組,當(dāng)方法中拋出指定異常名稱數(shù)組中的異常時(shí),則進(jìn)行事務(wù)回滾。例如:指定單一異常類名稱@Transactional(rollbackForClassName=”RuntimeException”)指定多個(gè)異常類名稱:@Transactional(rollbackForClassName={“RuntimeException”,”Exception”})
-
noRollbackFor
該屬性用于設(shè)置不需要進(jìn)行回滾的異常類數(shù)組,當(dāng)方法中拋出指定異常數(shù)組中的異常時(shí),不進(jìn)行事務(wù)回滾。例如:指定單一異常類:@Transactional(noRollbackFor=RuntimeException.class)指定多個(gè)異常類:@Transactional(noRollbackFor={RuntimeException.class, Exception.class})
-
noRollbackForClassName
該屬性用于設(shè)置不需要進(jìn)行回滾的異常類名稱數(shù)組,當(dāng)方法中拋出指定異常名稱數(shù)組中的異常時(shí),不進(jìn)行事務(wù)回滾。例如:指定單一異常類名稱:@Transactional(noRollbackForClassName=”RuntimeException”)指定多個(gè)異常類名稱:@Transactional(noRollbackForClassName={“RuntimeException”,”Exception”})
-
propagation
該屬性用于設(shè)置事務(wù)的傳播行為。例如:@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
-
isolation
該屬性用于設(shè)置底層數(shù)據(jù)庫(kù)的事務(wù)隔離級(jí)別,事務(wù)隔離級(jí)別用于處理多事務(wù)并發(fā)的情況,通常使用數(shù)據(jù)庫(kù)的默認(rèn)隔離級(jí)別即可,基本不需要進(jìn)行設(shè)置
-
timeout
該屬性用于設(shè)置事務(wù)的超時(shí)秒數(shù),默認(rèn)值為-1表示永不超時(shí)
失效場(chǎng)景
- @Transactional 應(yīng)用在非 public 修飾的方法上
- 數(shù)據(jù)庫(kù)引擎要不支持事務(wù)
- 由于propagation 設(shè)置錯(cuò)誤,導(dǎo)致注解失效
- rollbackFor 設(shè)置錯(cuò)誤,@Transactional 注解失效
- 方法之間的互相調(diào)用也會(huì)導(dǎo)致@Transactional失效
- 異常被你的 catch“吃了”導(dǎo)致@Transactional失效