事務
能夠理解爲一個 獨立的
工做單元, 在這個獨立的工做單元中, 有一組操做; 放在事務(獨立工做單元)中的多個操做, 要麼所有執行成功, 要麼所有執行失敗。難免俗套, 這仍是經過最經典的銀行轉帳
應用來解釋一下mysql
假設有兩個角色 'Iron Man'(餘額500), 'Wolverine'(餘額15), 如今 Iron Man
經過該銀行應用給 Wolverine
轉帳100元, 那麼本次轉帳操做至少須要三個步驟:sql
檢查`Iron Man`餘額`>=100`元 從`Iron Man`餘額中`-100`元 給`Wolverine`餘額`+100`元
獨立的工做單元
來執行。在這個 獨立工做單元
(即事務) 中的這三個操做, 只要有任何一個操做失敗, 則事務就總體就是失敗的, 那就必須回滾全部的步驟。在分析高併發事務的問題前, 咱們要先知道事務的幾個標準特性, 由於一個運行良好的事務處理系統必須具有這些標準特性, 並且這些問題的解決離不開事務的這幾個標準特性!!!數據庫
一個不可分割的最小工做單元
, 整個事務中的全部操做要麼所有提交成功, 要麼所有失敗回滾。對於一個事務來講, 不能只成功執行其中的一部分操做, 這就是事務的原子性。Consistency 一致性
雖然可數據表中的數據可能一直在變化, 可是事務的一致性
特性會保證 數據庫老是從一個一致性的狀態 轉換到 另外一個一致性的狀態;segmentfault
好比在以前的轉帳例子:併發
轉帳前的一致性狀態是: 'Iron Man'(餘額500), 'Wolverine'(餘額15) 轉帳成功後的一致性狀態是: 'Iron Man'(餘額400), 'Wolverine'(餘額115) 轉帳若是失敗的話, 一致性的狀態應該回滾到轉帳前的狀態: 'Iron Man'(餘額500), 'Wolverine'(餘額15)
Isolation 隔離性高併發
-100
的餘額纔對隔離性
的 隔離級別
, 到時候就知道這裏爲何說一般來講
對其餘事務是不可見的; (也就是還有特例, 好比最低隔離級別 READ UNCOMMITTED
, 對其餘事務的可見就形成了髒讀問題
的出現)READ UNCOMMITTED
, READ COMMITTED
, REPEATABLE READ
, SERIALIZABLE
)Durability 持久性性能
一旦事務被最終提交, 則在事務這個獨立單元中的全部操做所作的修改將會 `永久保存到數據庫中`; (這裏所說的`永久`應該能夠理解爲 被事務修改的數據 是真正存放到了表中, 而不是存放在了諸如臨時表之類的地方)
在併發量比較大的時候, 很容易出現 多個事務同時進行 的狀況。假設有兩個事務正在同時進行, 值得注意的是: 它們二者之間是互相不知道對方的存在的, 各自都對自身所處的環境過度樂觀, 從而並無對本身所操做的數據作必定的保護處理, 因此最終致使了一些問題的出現;
接下來, 在分析高併發事務的問題時, 你可能已經瞭解了一些關於鎖的概念, 可是在分析這些問題的時候, 先不要帶入鎖的概念, 本小節只會列出問題, 並直接告訴你各個問題是使用事務隔離性的哪一個隔離級別解決掉的, 鎖是解決方案, 若是帶入鎖的概念, 是沒法去分析這些問題的。因此本節不須要帶入鎖
!
[下一篇文章]()將會分析這些解決方案(各隔離級別)具體是如何解決問題的。spa
若是mysql中一個事務A讀取了另外一個並行事務B未最終提交的寫數據, 那事務A的此次讀取就是髒讀
。(由於事務A讀取的是'髒數據', 是'非持久性'的數據)code
髒數據
, 由於事務B最終會回滾這個數據, 因此若是事務A使用庫存20進行後續的操做, 就會引起問題, 由於事務A拿到的數據已經和表中的真實數據不一致了。那麼這個問題如何解決呢?
在MySQL中, 其實事務已經用自身特性(隔離性
的 -- READ COMMITED
或以上隔離級別)解決了這個問題;blog
**`READ COMMITED`級別保證了, 只要是當前語句執行前已經提交的數據都是可見的**。注意和`REPEATABLE READ`級別的區!!!
髒讀問題
已經被徹底解決了, 那就意味着事務中每次讀取到的數據都是 持久性
的數據(被別的事務最終 提交/回滾 完成後的數據)。隔離性
的 -- REPEATABLE READ
或以上隔離級別)解決了這個問題;REPEATABLE READ
級別保證了, 只要是當前事務執行前已經提交的數據都是可見的。注意和READ COMMITED
級別的區!!!對於幻讀, 可能不少人常常和不可重複讀區分不開, 詳情能夠參考本人寫的此篇文章https://segmentfault.com/a/11...
高併發事務
的另外一個問題 -- 丟失更新問題
, 該問題和以前幾個問題須要區分開, 由於解決方案不是一類!此類更新丟失問題, 沒法依靠前三種隔離級別來解決, 只能用最高隔離級別 Serializable
或者手動使用樂觀鎖
, 悲觀鎖
來解決。
Serializable
在實際應用場景中並不被採用, 對於手動使用樂觀鎖
, 悲觀鎖
的方案, 將會在之後關於鎖的文章中一併給出!參考資料: