SQL 隔離級別與事務

2021-09-14 01:55:33 字數 1427 閱讀 2429

前言:

事物:事物是指一組原子性的sql查詢。(如:銀行轉賬:a要轉賬給b100,在資料庫中至少三步 1.a的賬戶查詢餘額大於100,2.a賬戶減少100,3.b的賬戶要增加100這樣這個事物才算真的完成,這裡的幾條sql語句應該一起完成或者失敗,失敗就會發生回滾,成功則提交事務。)。

隔離:隔離的產生主要是在併發情況下讀取資料可能出現髒讀,不可重複讀和幻讀的情況。因為併發的存在,可能會出現同一時間,多個人對乙個資料或者表查詢或者修改。

本文參考了:

事務的原子性,隔離性,一致性和永續性。

原子性:對於乙個事務來說,不可能只執行其中的一部分操作。

一致性:資料庫總是從乙個一致性狀態轉換到另乙個一致性狀態。在轉賬表示中則是總體的錢是不變的,如資料庫中總共有1000元,則事務完成後還是1000元,不同的是其中的幾個賬戶的錢變了。

隔離性:一般來說,乙個事務做的修改提交前,對於其他事務不可見。比如上面轉賬例子中,若a賬戶原來有200元,執行到第二步a賬戶減少100,此時還沒有把事務執行提交,那麼當另外乙個事務查詢a賬戶餘額時仍然為200。(這只是一般情況,如果真的這樣我想不會出現髒讀了)

永續性:永續性是個模糊的概念,它是指:一旦事務提交,它的修改就會永久儲存到資料庫中,系統崩潰也不會丟失。這個我覺得就不是我們需要考慮的了,天災人禍,洪水旱澇,聽天由命。

資料庫併發訪問出現的問題:

髒讀:所謂的髒讀,其實就是讀到了別的事務回滾前的髒資料。比如事務b執行過程中修改了資料x,在未提交前,事務a讀取了x,而事務b卻回滾了,這樣事務a就形成了髒讀。如:轉賬問題,到了第三步時,新來的事務訪問b餘額是100,但是發現b賬戶出了問題,於是回滾了,b餘額又是200了,導致錯誤。

不可重複讀:比如現在有乙個事務要讀取兩次a的餘額,第一次讀取餘額在轉賬之前,是200,但是第二次讀取時,a已經完成轉賬,讀取為100,這就是不可重複讀。

幻讀:幻讀和不可重複讀差不多,不過不可重複讀針對的是資料不一樣,而幻讀針對讀取時的資料量不一樣,比如查詢餘額為200的人,第一次查詢為n個(此時包括a),第二次查詢時a轉完賬了,此時查詢結果為(n-1)。

第一類丟失更新,第二類丟失更新。這個直接看的網上,第一類丟失更新中事務撤銷不是特別理解,但是第二類就相當於一次提交覆蓋另一次提交吧。

read uncommitted(未提交讀):事務中的修改,即使沒有提交對其他事務也是可見的。(不滿足隔離性)。

read commited(提交讀):解決了髒讀。大多數資料庫預設隔離級別都是這個(但mysql不是)。它滿足隔離性的簡單定義:乙個事務開始時只能看見已經提交的事務所做的修改(好拗口,慢慢理解)。

repeatable read(可重複讀):解決了髒讀的問題和不可重複讀問題。保證了同乙個事務多次提取同樣資料結果一樣。但理論上為解決幻讀問題。

serializable(可序列化):隔離級別最高,強制事務序列化,相當於沒有併發。

事務的隔離級別和資料庫併發性是成反比的,隔離級別越高,併發性越低 。

SQL 事務隔離級別

髒讀 包含未提交資料的讀。例如,事務1 更改了某行。事務2 在事務1 提交更改之前讀取已更改的行。如果事務1 回滾更改,則事務2 便讀取了邏輯上從未存在過的行。不可重複讀取 當某個事務不止一次讀取同一行,並且乙個單獨的事務在兩次 或多次 讀取之間修改該行時。因為在同乙個事務內的多次讀取之間修改了該行...

SQL中事務的隔離級別

sql server隔離 收藏 sql server隔離語句如下 set transaction isolation level read uncommitted read committed repeatable read snapshot serializable 一次只能設定乙個隔離級別選項,...

深入講解SQL事務隔離級別

因為需要併發能力 所以我們不能用上一節的序列化的方式 來滿足併發 需要降低資料庫的隔離級別,來換取事務的併發能力 三種異常問題 髒讀 事務還沒提交,小李已經讀到了資料 不可重複讀 在事務操作中間時修改記錄,另乙個人兩次的查詢結果不一樣 幻讀 某人先查詢了n條資料,正好同時某人提交了增加資料,下一次查...