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