spring事物簡單分析
一、資料庫事物的基本特性
1、事物是區分檔案儲存系統與Nosql資料庫重要特性之一,其存在的意義是為了保證即使在併發情況下也能正確的執行crud操作。怎樣才算是正確的呢?這時提出了事物需要保證的四個特性即ACID:
A: 原子性(atomicity)
事物中各項操作,要麼全做要麼全不做,任何一項操作的失敗都會導致整個事物的失敗;
C: 一致性(consistency)
事物結束後系統狀態是一致的
I:隔離性(isolation)
併發執行的事物彼此無法看到對方的中間狀態;
D: 永續性(durability)
事物完成後所做的改動都會被持久化,即使發生災難性的失敗
2、在高併發的情況下,要完全保證其ACID特性是非常困難的,除非把所有的事物序列化執行,但帶來的負面的影響將是效能大打折扣。很多時候我們有些業務對事物的要求是不一樣的,所以資料庫中設計了四種隔離級別,供使用者基於業務進行選擇。
髒讀 :一個事物讀取到另一事物未提交的更新資料
不可重複讀 : 在同一事物中,多次讀取同一資料返回的結果有所不同, 換句話說, 後續讀取可以讀到另一事物已提交的更新資料. 相反, “可重複讀”在同一事物中多次讀取資料時, 能夠保證所讀資料一樣, 也就是後續讀取不能讀到另一事物已提交的更新資料。
幻讀 :查詢表中一條資料如果不存在就插入一條,併發的時候卻發現,裡面居然有兩條相同的資料。這就幻讀的問題。
隔離級別 |
髒讀(Dirty Read) |
不可重複讀(NonRepeatable Read) |
幻讀(Phantom Read) |
未提交讀(Read uncommitted) |
可能 |
可能 |
可能 |
已提交讀(Read committed) |
不可能 |
可能 |
可能 |
可重複讀(Repeatable read) |
不可能 |
不可能 |
可能 |
可序列化(SERIALIZABLE) |
不可能 |
不可能 |
不可能 |
資料庫預設隔離級別:
Oracle中預設級別是 Read committed
mysql 中預設級別 Repeatable read。另外要注意的是mysql 執行一條查詢語句預設是一個獨立的事物,所以看上去效果跟Read committed一樣。
3、spring事物的轉播機制
類別 |
事物傳播型別 |
說明 |
支援當前事物 |
PROPAGATION_REQUIRED (必須的) |
如果當前沒有事物,就新建一個事物,如果已經存在一個事物中,加入到這個事物中。這是最常見的選擇。 |
PROPAGATION_SUPPORTS (支援) |
支援當前事物,如果當前沒有事物,就以非事物方式執行。 |
|
PROPAGATION_MANDATORY (強制) |
使用當前的事物,如果當前沒有事物,就丟擲異常。 |
|
不支援當前事物 |
PROPAGATION_REQUIRES_NEW (隔離) |
新建事物,如果當前存在事物,把當前事物掛起。 |
PROPAGATION_NOT_SUPPORTED (不支援) |
以非事物方式執行操作,如果當前存在事物,就把當前事物掛起。 |
|
PROPAGATION_NEVER (強制非事物) |
以非事物方式執行,如果當前存在事物,則丟擲異常。 |
|
套事物 |
PROPAGATION_NESTED (巢狀事物) |
如果當前存在事物,則在巢狀事物內執行。如果當前沒有事物,則執行與PROPAGATION_REQUIRED類似的操作。 |