Java提升篇-事务隔离级别和传播机制
轉(zhuǎn)載自?Java提升篇-事務(wù)隔離級別和傳播機(jī)制
問題的提出
為了保證并發(fā)操作數(shù)據(jù)的正確性及一致性,SQL規(guī)范于1992年提出了數(shù)據(jù)庫事務(wù)隔離級別。
事務(wù)隔離級別分類
事務(wù)隔離級別由低往高可分為以下幾類
READ UNCOMMITTED,讀取未提交的數(shù)據(jù)。
這是最不安全的一種級別,查詢語句在無鎖的情況下運(yùn)行,并能讀取到別的未提交的數(shù)據(jù),造成臟讀,如果未提交的那個(gè)事務(wù)數(shù)據(jù)全部回滾了,而之前讀取了這個(gè)事務(wù)的數(shù)據(jù)即是臟數(shù)據(jù),這種數(shù)據(jù)不一致性讀造成的危害是可想而知的。
READ COMMITTED,讀取已提交的數(shù)據(jù)。
????????一個(gè)事務(wù)只能讀取數(shù)據(jù)庫中已經(jīng)提交過的數(shù)據(jù),解決了臟讀問題,但不能重復(fù)讀,即一個(gè)事務(wù)內(nèi)的兩次查詢返回的數(shù)據(jù)是不一樣的。如第一次查詢金額是100,第二次去查詢可能就是50了,這就是不可重復(fù)讀取。
????? ?
REPEATABLE READ,可重復(fù)讀取數(shù)據(jù),這也是Mysql默認(rèn)的隔離級別。
???? 一個(gè)事務(wù)內(nèi)的兩次無鎖查詢返回的數(shù)據(jù)都是一樣的,但別的事務(wù)的新增數(shù)據(jù)也能讀取到。比如另一個(gè)事務(wù)插入了一條數(shù)據(jù)并提交,這個(gè)事務(wù)第二次去讀取的時(shí)候發(fā)現(xiàn)多了一條之前查詢數(shù)據(jù)列表里面不存在的數(shù)據(jù),這時(shí)候就是傳說的中幻讀了。這個(gè)級別避免了不可重復(fù)讀取,但不能避免幻讀的問題。
SERIALIZABLE,可串行化讀。
????這是效率最低最耗費(fèi)資源的一個(gè)事務(wù)級別,和可重復(fù)讀類似,但在自動提交模式關(guān)閉情況下可串行化讀會給每個(gè)查詢加上共享鎖和排他鎖,意味著所有的讀操作之間不阻塞,但讀操作會阻塞別的事務(wù)的寫操作,寫操作也阻塞讀操作。
上面介紹了4種事務(wù)隔離級別及臟讀、不可重復(fù)讀、幻讀與它們的聯(lián)系,對應(yīng)的關(guān)系表如下:
| 讀取未提交 | √ | √ | √ |
| 讀取已提交 | × | √ | √ |
| 可重復(fù)讀 | × | × | √ |
| 可串行化讀 | × | × | × |
Mysql官方對于事務(wù)級別的定義可參考:
https://dev.mysql.com/doc/refman/5.7/en/innodb-transaction-isolation-levels.html
擴(kuò)展
上面介紹的是Mysql的事務(wù)隔離級別,那跟spring中的事務(wù)隔離級別有什么必然的聯(lián)系呢?
spring就是對數(shù)據(jù)庫事務(wù)進(jìn)行了封裝而已,并提了5種事務(wù)隔離級別和7種事務(wù)傳播機(jī)制。
5種事務(wù)隔離級別
ISOLATION_DEFAULT
spring將使用數(shù)據(jù)庫中默認(rèn)的事務(wù)隔離級別。
下面四種定義和上面一致。
ISOLATION_READ_UNCOMMITTED?4 p" L. I' F; k1 {) a. D( E5 ?: V
ISOLATION_READ_COMMITTED
ISOLATION_REPEATABLE_READ
ISOLATION_SERIALIZABLE
7種事務(wù)傳播機(jī)制
REQUIRED
如果當(dāng)前方法有事務(wù)則加入事務(wù),沒有則創(chuàng)建一個(gè)事務(wù)。
NOT_SUPPORTED
不支持事務(wù),如果當(dāng)前有事務(wù)則掛起事務(wù)運(yùn)行。
REQUIREDS_NEW
新建一個(gè)事務(wù)并在這個(gè)事務(wù)中運(yùn)行,如果當(dāng)前存在事務(wù)就把當(dāng)前事務(wù)掛起。新建的事務(wù)的提交與回滾一掛起事務(wù)沒有聯(lián)系,不會影響掛起事務(wù)的操作。
MANDATORY
強(qiáng)制當(dāng)前方法使用事務(wù)運(yùn)行,如果當(dāng)前沒有事務(wù)則拋出異常。
NEVER
當(dāng)前方法不能存在事務(wù),即非事務(wù)狀態(tài)運(yùn)行,如果存在事務(wù)則拋出異常。
SUPPORTS
支持當(dāng)前事務(wù),如果當(dāng)前沒事務(wù)也支持非事務(wù)狀態(tài)運(yùn)行。
NESTED
如果當(dāng)前存在事務(wù),則在嵌套事務(wù)內(nèi)執(zhí)行。嵌套事務(wù)的提交與回滾與父事務(wù)沒有任務(wù)關(guān)系,反之,當(dāng)父事務(wù)提交嵌套事務(wù)也一起提交,父事務(wù)回滾會也回滾嵌套事務(wù)的。
如果當(dāng)前沒有事務(wù),則新建一個(gè)事務(wù)運(yùn)行,這時(shí)候則與PROPAGATION_REQUIRED場景一致。
總結(jié)
以上是生活随笔為你收集整理的Java提升篇-事务隔离级别和传播机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win11 怎么检查硬件?
- 下一篇: 关于Java序列化你应该知道的一切