1. 程式人生 > >資料庫隔離級別的原理解析

資料庫隔離級別的原理解析

  廣告:      

        樂觀鎖:(select for update)先查詢要更新的記錄,做個標記,更新的時候根據標記條件更新,返回是否有資料更新,如果失敗。表示被其他人或事務更新過了,捷足先登了。悲觀鎖: 基於資料庫鎖機制建立(一種不信任鎖).讀的時候就被鎖了

1,髒讀

  髒讀是指在一個事務處理過程裡讀取了另一個未提交的事務中的資料。

  當一個事務正在多次修改某個資料,而在這個事務中這多次的修改都還未提交,這時一個併發的事務來訪問該資料,就會造成兩個事務得到的資料不一致。例如:使用者A向用戶B轉賬100元,對應SQL命令如下

    update account set money=money+100 where name=’B’;  (此時A通知B)

    update account set money=money - 100 where name=’A’;

  當只執行第一條SQL時,A通知B檢視賬戶,B發現確實錢已到賬(此時即發生了髒讀),而之後無論第二條SQL是否執行,只要該事務不提交,則所有操作都將回滾,那麼當B以後再次檢視賬戶時就會發現錢其實並沒有轉。

2,不可重複讀

  不可重複讀是指在對於資料庫中的某個資料,一個事務範圍內多次查詢卻返回了不同的資料值,這是由於在查詢間隔,被另一個事務修改並提交了。

  例如事務T1在讀取某一資料,而事務T2立馬修改了這個資料並且提交事務給資料庫,事務T1再次讀取該資料就得到了不同的結果,傳送了不可重複讀。

  不可重複讀和髒讀的區別是,髒讀是某一事務讀取了另一個事務未提交的髒資料,而不可重複讀則是讀取了前一事務提交的資料。

  在某些情況下,不可重複讀並不是問題,比如我們多次查詢某個資料當然以最後查詢得到的結果為主。但在另一些情況下就有可能發生問題,例如對於同一個資料A和B依次查詢就可能不同,A和B就可能打起來了……

3,虛讀(幻讀)

  幻讀是事務非獨立執行時發生的一種現象。例如事務T1對一個表中所有的行的某個資料項做了從“1”修改為“2”的操作,這時事務T2又對這個表中插入了一行資料項,而這個資料項的數值還是為“1”並且提交給資料庫。而操作事務T1的使用者如果再檢視剛剛修改的資料,會發現還有一行沒有修改,其實這行是從事務T2中新增的,就好像產生幻覺一樣,這就是發生了幻讀。

  幻讀和不可重複讀都是讀取了另一條已經提交的事務(這點就髒讀不同),所不同的是不可重複讀查詢的都是同一個資料項,而幻讀針對的是一批資料整體(比如資料的個數)。

     補充:不可重複讀是能讀到其它事務已經提交的資料,幻讀是讀不到其它事務已提交的資料!

解析資料庫隔離級別實現原理

   mysql鎖機制分為表級鎖和行級鎖,本文就和大家分享一下我對mysql中行級鎖中的共享鎖與排他鎖進行分享交流。

   共享鎖又稱為讀鎖,簡稱S鎖,顧名思義,共享鎖就是多個事務對於同一資料可以共享一把鎖,都能訪問到資料,但是隻能讀不能修改。

   排他鎖又稱為寫鎖,簡稱X鎖,顧名思義,排他鎖就是不能與其他所並存,如一個事務獲取了一個數據行的排他鎖,其他事務就不能再獲取該行的其他鎖,包括共享鎖和排他鎖,但是獲取排他鎖的事務是可以對資料就行讀取和修改。

READ UNCOMMITTED指定語句可以讀取已由其他事務修改但尚未提交的行。 在 READ UNCOMMITTED 級別執行的事務,不會發出共享鎖來防止其他事務修改當前事務讀取的資料。READ UNCOMMITTED 事務也不會被排他鎖阻塞,排他鎖會禁止當前事務讀取其他事務已修改但尚未提交的行。設定此選項之後,可以讀取未提交的修改,這種讀取稱為髒讀。在事務結束之前,可以更改資料中的值,修改的行也可以出現在資料集中或從資料集中消失。該選項的作用與在事務內所有 SELECT 語句中的所有表上設定 NOLOCK 相同。這是隔離級別中限制最少的級別。(如果一個事務已經開始寫資料,則另外一個事務則不允許同時進行寫操作,但允許其他事務讀此行資料;其實任何情況下,一個事務沒提交時是沒有釋放鎖的,所以其他事務就不能同時寫操作)

READ COMMITTED 指定語句不能讀取已由其他事務修改但尚未提交的資料。這樣可以避免髒讀。其他事務可以在當前事務的各個語句之間更改資料,從而產生不可重複讀取和幻像資料。該選項是 SQL Server 的預設設定。(讀取資料的事務允許其他事務繼續訪問該行資料,但是未提交的寫事務將會禁止其他事務訪問該行)

REPEATABLE READ指定語句不能讀取已由其他事務修改但尚未提交的行,並且指定,其他任何事務都不能在當前事務完成之前修改由當前事務讀取的資料。 對事務中的每個語句所讀取的全部資料都設定了共享鎖,並且該共享鎖一直保持到事務完成為止。這樣可以防止其他事務修改當前事務讀取的任何行。但是其他事務可以插入與當前事務所發出語句的搜尋條件相匹配的新行。如果當前事務隨後重試執行該語句,它會檢索新行,從而產生幻讀。由於共享鎖一直保持到事務結束,而不是在每個語句結束時釋放,所以併發級別低於預設的 READ COMMITTED 隔離級別。此選項只在必要時使用。(讀取資料的事務將會禁止寫事務(但允許讀事務),寫事務則禁止任何其他事務)

Serializable實現原理(提供嚴格的事務隔離。它要求事務序列化執行,事務只能一個接著一個地執行,但不能併發執行)

REPEATABLE READ加上一個間隙鎖的功能能解決[每人限制抽獎不同步的問題]。間隙鎖指的是當對資料進行條件,範圍檢索時,對其範圍內也許並存在的值進行加鎖!這樣就可以遮蔽幻讀的發生。其他的事務不能在這個事務查詢的範圍內插入新值。(間隙鎖使用不當容易造成全表鎖)