天天看點

資料庫隔離級别

資料庫隔離級别有四種,應用《高性能mysql》一書中的說明:

資料庫隔離級别
資料庫隔離級别
資料庫隔離級别

然後說說修改事務隔離級别的方法:

1.全局修改,修改mysql.ini配置檔案,在最後加上

這裡全局預設是repeatable-read,其實mysql本來預設也是這個級别

2.對目前session修改,在登入mysql用戶端後,執行指令:

資料庫隔離級别

要記住mysql有一個autocommit參數,預設是on,他的作用是每一條單獨的查詢都是一個事務,并且自動開始,自動送出(執行完以後就自動結束了,如果你要适用select for update,而不手動調用 start transaction,這個for update的行鎖機制等于沒用,因為行鎖在自動送出後就釋放了),是以事務隔離級别和鎖機制即使你不顯式調用start transaction,這種機制在單獨的一條查詢語句中也是适用的,分析鎖的運作的時候一定要注意這一點

再來說說鎖機制:

共享鎖:由讀表操作加上的鎖,加鎖後其他使用者隻能擷取該表或行的共享鎖,不能擷取排它鎖,也就是說隻能讀不能寫

排它鎖:由寫表操作加上的鎖,加鎖後其他使用者不能擷取該表或行的任何鎖,典型是mysql事務中的

鎖的範圍:

行鎖: 對某行記錄加上鎖

表鎖: 對整個表加上鎖

這樣組合起來就有,行級共享鎖,表級共享鎖,行級排他鎖,表級排他鎖

start transaction; select * from user where userid = 1 for update;

執行完這句以後

  1)當其他事務想要擷取共享鎖,比如事務隔離級别為serializable的事務,執行

  select * from user;

   将會被挂起,因為serializable的select語句需要擷取共享鎖

  2)當其他事務執行

  select * from user where userid = 1 for update;   update user set userage = 100 where userid = 1; 

  也會被挂起,因為for update會擷取這一行資料的排它鎖,需要等到前一個事務釋放該排它鎖才可以繼續進行

下面來說說不同的事務隔離級别的執行個體效果,例子使用innodb,開啟兩個用戶端a,b,在a中修改事務隔離級别,在b中開啟事務并修改資料,然後在a中的事務檢視b的事務修改效果:

1.read-uncommitted(讀取未送出内容)級别

  1)a修改事務級别并開始事務,對user表做一次查詢

   

資料庫隔離級别

  2)b更新一條記錄

資料庫隔離級别

  3)此時b事務還未送出,a在事務内做一次查詢,發現查詢結果已經改變

資料庫隔離級别

  4)b進行事務復原

資料庫隔離級别

  5)a再做一次查詢,查詢結果又變回去了

資料庫隔離級别

  6)a表對user表資料進行修改

資料庫隔離級别

  7)b表重新開始事務後,對user表記錄進行修改,修改被挂起,直至逾時,但是對另一條資料的修改成功,說明a的修改對user表的資料行加行共享鎖(因為可以使用select)

資料庫隔離級别

  可以看出read-uncommitted隔離級别,當兩個事務同時進行時,即使事務沒有送出,所做的修改也會對事務内的查詢做出影響,這種級别顯然很不安全。但是在表對某行進行修改時,會對該行加上行共享鎖

2. read-committed(讀取送出内容)

  1)設定a的事務隔離級别,并進入事務做一次查詢

資料庫隔離級别

  2)b開始事務,并對記錄進行修改

資料庫隔離級别

  3)a再對user表進行查詢,發現記錄沒有受到影響

資料庫隔離級别

  4)b送出事務

資料庫隔離級别

  5)a再對user表查詢,發現記錄被修改

資料庫隔離級别

  6)a對user表進行修改

資料庫隔離級别

  7)b重新開始事務,并對user表同一條進行修改,發現修改被挂起,直到逾時,但對另一條記錄修改,卻是成功,說明a的修改對user表加上了行共享鎖(因為可以select)

資料庫隔離級别
資料庫隔離級别

  read-committed事務隔離級别,隻有在事務送出後,才會對另一個事務産生影響,并且在對表進行修改時,會對表資料行加上行共享鎖

3. repeatable-read(可重讀)

  1)a設定事務隔離級别,進入事務後查詢一次

資料庫隔離級别

  2)b開始事務,并對user表進行修改

資料庫隔離級别

  3)a檢視user表資料,資料未發生改變

資料庫隔離級别
資料庫隔離級别

  5)a再進行一次查詢,結果還是沒有變化

資料庫隔離級别

  6)a送出事務後,再檢視結果,結果已經更新

資料庫隔離級别

  7)a重新開始事務,并對user表進行修改

資料庫隔離級别

  8)b表重新開始事務,并對user表進行修改,修改被挂起,直到逾時,對另一條記錄修改卻成功,說明a對表進行修改時加了行共享鎖(可以select)

資料庫隔離級别
資料庫隔離級别

  repeatable-read事務隔離級别,當兩個事務同時進行時,其中一個事務修改資料對另一個事務不會造成影響,即使修改的事務已經送出也不會對另一個事務造成影響。

  在事務中對某條記錄修改,會對記錄加上行共享鎖,直到事務結束才會釋放。

4.serierlized(可串行化)

  1)修改a的事務隔離級别,并作一次查詢

資料庫隔離級别

  2)b對表進行查詢,正常得出結果,可知對user表的查詢是可以進行的

資料庫隔離級别

  3)b開始事務,并對記錄做修改,因為a事務未送出,是以b的修改處于等待狀态,等待a事務結束,最後逾時,說明a在對user表做查詢操作後,對表加上了共享鎖

資料庫隔離級别

  serializable事務隔離級别最嚴厲,在進行查詢時就會對表或行加上共享鎖,其他事務對該表将隻能進行讀操作,而不能進行寫操作。