1. 程式人生 > >事物隔離級別和Spring事物傳播特性

事物隔離級別和Spring事物傳播特性

1.關於事物

1.事務是程式中一系列嚴密的操作,所有一系列操作執行必須成功完成,否則在每個操作所做的更改將會被撤銷,要麼全執行,要麼全不執行。
2.事務特性有分為四個:原子性、一致性、隔離性、持續性。

    原子性:事務是資料庫邏輯工作單元,事務中包含的操作要麼都執行成功,要麼都執行失敗。
    一致性:事務執行的結果必須是使資料庫資料從一個一致性狀態變到另外一種一致性狀態。
            這些未完成事務對資料庫所做的修改有一部分已寫入物理資料庫,這是資料庫就處於不一致狀態。
    隔離性:一個事務的執行過程中不能影響到其他事務的執行,即一個事務內部的操作及使用的資料對其他事務是隔離的,
            併發執行各個事務之間無不干擾。
    持續性:即一個事務執一旦提交,它對資料庫資料的改變是永久性的。之後的其它操作不應該對其執行結果有任何影響。

2.事物的隔離級別

1.資料庫事務的隔離級別有4種,由低到高分別為Read uncommitted 、Read committed 、Repeatable read 、Serializable 。四種隔離級別用來解決事物併發操作中可能會出現髒讀,不可重複讀,幻讀,丟失更新1,丟失更新2等問題。

2.事物併發中可能出現的問題:

    髒讀:指當一個事務正字訪問資料,並且對資料進行了修改,而這種資料還沒有提交到資料庫中,這時,另外一個事務
            也訪問這個資料,然後使用了這個資料。因為這個資料還沒有提交那麼另外一個事務讀取到的這個資料我們稱之為髒資料。
            依據髒資料所做的操作肯能是不正確的。
    不可重複讀:指在一個事務內,多次讀同一資料。在這個事務還沒有執行結束,另外一個事務也訪問該同一資料,
            那麼在第一個事務中的兩次讀取資料之間,由於第二個事務的修改第一個事務兩次讀到的資料可能是不一樣的,
            這樣就發生了在一個事物內兩次連續讀到的資料是不一樣的,這種情況被稱為是不可重複讀。
    幻讀:一個事務先後讀取一個範圍的記錄,但兩次讀取的紀錄數不同,我們稱之為幻象讀
        (兩次執行同一條 select 語句會出現不同的結果,第二次讀會增加一資料行,並沒有說這兩次執行是在同一個事務中)
    丟失更新1:A,B讀取資料並更新,A回退造成B的更新丟失。
    丟失更新2:A不回退造成B的更新丟失。

3.四種隔離級別

  • read uncommited(讀未提交):是最低的事務隔離級別,它允許另外一個事務可以看到這個事務未提交的資料。可防止丟失更新。
    實現原理:讀資料時候不加鎖,寫資料時候加行級共享鎖,提交時釋放鎖(防止丟失更新)。
  • read commited(讀已提交):保證一個事物提交後才能被另外一個事務讀取。另外一個事務不能讀取該事物未提交的資料。可以防止髒讀問題。
    實現原理:事務讀取資料(讀到資料的時候)加行級共享鎖,讀完釋放;事務寫資料時候(寫操作發生的瞬間)加行級排他鎖,事務結束釋放。
  • repeatable read(重複讀):這種事務隔離級別可以防止髒讀,不可重複讀。但是可能會出現幻象讀。
    實現原理:和讀提交資料不同的是,事務讀取資料在讀操作開始的瞬間就加上行級共享鎖,而且在事務結束的時候才釋放。事務寫資料時候(寫操作發生的瞬間)加行級排他鎖,事務結束釋放。

  • serializable(序列化):這是花費最高代價但最可靠的事務隔離級別。事務被處理為順序執行。除了防止髒讀,不可重複讀之外,還避免了幻象讀。
    實現原理:在讀操作時,加表級共享鎖,事務結束時釋放;寫操作時候,加表級排他鎖,事務結束時釋放
    這裡寫圖片描述

Mysql資料庫預設的隔離級別是repeatable read

4.spring事務傳播特性:

事務傳播行為就是多個事務方法相互呼叫時,事務如何在這些方法間傳播。spring支援7種事務傳播行為:

1.propagation_requierd:如果當前沒有事務,就新建一個事務,如果已存在一個事務中,加入到這個事務中,這是最常見的選擇。
2.propagation_supports:支援當前事務,如果沒有當前事務,就以非事務方法執行。
3.propagation_mandatory:使用當前事務,如果沒有當前事務,就丟擲異常。
4.propagation_required_new:新建事務,如果當前存在事務,把當前事務掛起。
5.propagation_not_supported:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
6.propagation_never:以非事務方式執行操作,如果當前事務存在則丟擲異常。
7.propagation_nested:如果當前存在事務,則在巢狀事務內執行。如果當前沒有事務,則執行與propagation_required類似的操作