數據庫事務知識點

一、ACID

  • 原子性( A ):事務是最小的單元,要麼全部成功,要麼全部回滾。
  • 一致性( C ):事務開始之前和事務結束以後,數據庫的完整性約束沒有被破壞。事務前後保持處於一致的狀態,不管在任何給定的時間併發事務有多少。一個事務是數據狀態的切換,因此,如果事務併發對個,系統也必須串行執行這些事務操作。
  • 隔離性( I ):多個事務併發訪問時,事務之間是隔離的,一個事務不應該影響其它事務運行效果。完全的隔離性是不現實的,完全的隔離性要求數據庫同一時間只執行一條事務,這樣會嚴重影響性能。
  • 持久性( D ):事務的結果不能丟失。

在併發環境下,事務的隔離性很難保證,從而引發併發一致性問題。

  • 髒讀:T1修改了一個數據,未提交之前被T2讀取到了。隨後T1撤銷了修改,T2讀到了髒數據。
  • 不可重複讀:T1讀取->T2修改->T1再讀。
  • 幻讀:T1select count()->T2insert->T1數據不準確
  • 丟失更改 ::T1更改->T2更改 T1更改失效

對於簡單的事務隔離性問題,我們可以通過設置事務隔開級別來保證數據一致性,通常通過@Transational註解來管理事務。其默認使用數據庫引擎默認的隔離級別。

  • READ_UNCOMMITTED:未授權讀取級別
    • 讀事務允許其他讀事務和寫事務,未提交的寫事務禁止其他寫事務(但允許其他讀事務)。可以防止丟失更改問題。
  • READ_COMMITTED:授權讀取級別
    • 讀事務允許其他讀事務和寫事務,未提交的寫事務禁止其他讀事務和寫事務。可以防止丟失更改,髒讀。
  • REPEATABLE_READ:可重複讀取級別
    • 讀事務禁止其他寫事務(但允許其他讀事務),未提交的寫事務禁止其他讀事務和寫事務。 可以防止丟失更改,髒讀,不可重複讀。
  • SERIALIZABLE:序列化級別
    • 一個一個走,並行轉串行。

數據庫的事務隔離級別的實現通常是通過加鎖或 undo log+MVCC實現。

以下原文鏈接

鎖實現

  • 未提交讀:一個update事務A只有在對數據修改時才加write lock,一旦寫完馬上釋放write lock,即使事務A還沒有提交。因此事務B在讀取同一行時,才能讀到事務A修改過的數據。

  • 提交讀:一個update事務A只有在對數據修改時才加write lock,但直到事務A commit時才釋放寫鎖。因此,同時進行的事務B希望讀取同一行數據時,會被事務A的write lock堵塞,所以解決了髒讀的問題。

  • 可重複讀:這個隔離等級的條件下,除了執行提交讀的寫鎖方式,還會在讀取一行數據後,爲這行數據添加read lock直至事務commit。例如,事務A讀取ID=1這一行數據,然後爲ID=1添加read lock。事務B同時希望update ID=1,此時獲取寫鎖失敗,因此在事務A執行完之前,沒有其他任何事務可以對ID=1這一行做修改,因此解決了重複讀的問題

雖然讀寫鎖解決了Isolation問題,但鎖會導致大量的堵塞,性能下降。某些時候會造成死鎖,爲了解決死鎖,還要添加死鎖探測機制,性能進一步下降,因此需要更高效的方式實現Isolation。

MVCC實現

MVCC實現
以上原文鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章