Mysql的鎖的問題

一、在可視化窗口執行select...for update,打開另外一個窗口,對同一行數據進行update,是能夠正常操做的。查詢才知道,窗口的select是自動進行事務提交的,若是要是for update生效,須要先執行begin,再select...for update,鎖生效,其餘窗口執行update會等待。mysql

 

繼而發現一片對事務說明舉例特別清晰的:sql

http://blog.csdn.net/jiangwei0910410003/article/details/24960785數據庫

數據庫隔離級別有四種:安全

READ-UNCOMMITTED 未提交讀,在該隔離級別,全部事務均可以看到其餘未提交事務的執行結果。
本隔離級別不多用於實際應用,由於它的性能也不比其餘級別好多少。讀取未提交的數據,也被稱之爲髒讀(Dirty Read)

READ-COMMITTED 提交讀,這是大多數數據庫系統的默認隔離級別(但不是MySQL默認的)。它知足了隔離的簡單定義:一個
事務只能看見已經提交事務所作的改變。這種隔離級別也支持所謂的不可重複讀(Nonrepeatable Read),由於同一事務的
其餘實例在該實例處理其間可能會有新的commit,因此同一select可能返回不一樣結果。

REPEATABLE-READ 重複讀, 這是MySQL的默認事務隔離級別,它確保同一事務的多個實例在併發讀取數據時,會看到一樣的數據
行。不過理論上,這會致使另外一個棘手的問題:幻讀(Phantom Read)。簡單的說,幻讀指當用戶讀取某一範圍的數據行時,
另外一個事務又在該範圍內插入了新行,當用戶再讀取該範圍的數據行時,會發現有新的「幻影」 行。InnoDB和Falcon存儲引擎經過
多版本併發控制(MVCC,Multiversion Concurrency Control)機制解決了該問題。
SERIALIZABLE 串行讀 這是最高的隔離級別,它經過強制事務排序,使之不可能相互衝突,從而解決幻讀問題。簡言之,它是在每
個讀的數據行上加上共享鎖。在這個級別,可能致使大量的超時現象和鎖競爭。

 

鎖機制:session

共享鎖:由讀表操做加上的鎖,加鎖後其餘用戶只能獲取該表或行的共享鎖,不能獲取排它鎖,也就是說只能讀不能寫併發

排它鎖:由寫表操做加上的鎖,加鎖後其餘用戶不能獲取該表或行的任何鎖,好比事務隔離級別爲SERIALIZABLE的事務,在一個事務進行select ...for update時,其餘事務select也會被掛起。性能

鎖的範圍:spa

行鎖: 對某行記錄加上鎖.net

表鎖: 對整個表加上鎖blog

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

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

 

修改事務級別的方法:

一、全局修改,修改mysql.ini配置文件,在最後加上

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

2.對當前session修改,在登陸mysql客戶端後,執行命令:

set session transaction isolation level read uncommitted;

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

相關文章
相關標籤/搜索