MySQL數據庫事務隔離級別(Transaction Isolation Level)

今天在學習JDBC的時候看到了關於MySql的事務的隔離級別的問題,感受內容挺高級的,因此記錄一篇文章,以備後面使用。mysql

數據庫隔離級別有四種,應用《高性能mysql》一書中的說明:sql

 

而後說說改動事務隔離級別的方法:數據庫

1.全局改動,改動mysql.ini配置文件。在最後加上安全

1 #可選參數有:READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE.
2 [mysqld]
3 transaction-isolation = REPEATABLE-READ

這裏全局默認是REPEATABLE-READ,事實上MySQL原本默認也是這個級別session

2.對當前session改動。在登陸mysqlclient後,運行命令:性能

set session transaction isolation level read uncommitted;學習

 

要記住mysql有一個autocommit參數。默認是on。他的做用是每一條單獨的查詢都是一個事務。並且本身主動開始。本身主動提交(運行完之後就本身主動結束了。假設你要適用select for update。而不手動調用 start transaction,這個for update的行鎖機制等於沒用。因爲行鎖在本身主動提交後就釋放了)。因此事務隔離級別和鎖機制即便你不顯式調用start transaction,這樣的機制在單獨的一條查詢語句中也是適用的,分析鎖的運做的時候必定要注意這一點spa

 

再來講說鎖機制:
共享鎖:由讀表操做加上的鎖。加鎖後其它用戶僅僅能獲取該表或行的共享鎖,不能獲取排它鎖,也就是說僅僅能讀不能寫3d

排它鎖:由寫表操做加上的鎖,加鎖後其它用戶不能獲取該表或行的不論什麼鎖。典型是mysql事務中code

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。開啓兩個clientA。B,在A中改動事務隔離級別,在B中開啓事務並改動數據,而後在A中的事務查看B的事務改動效果(兩個client至關因而兩個鏈接。在一個client中的改動參數變量的值是不會影響到另外的一個client的):

 

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表數據,數據未發生改變

   

 

  4)B提交事務

   

 

  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事務隔離級別最嚴厲,在進行查詢時就會對錶或行加上共享鎖。其它事務對該表將僅僅能進行讀操做。而不能進行寫操做。

相關文章
相關標籤/搜索