mysql高階之鎖(1)
簡介
鎖從力度上可以分為表鎖、頁鎖、行鎖。表鎖是將整張表鎖了,行鎖是將那一行鎖了。從對資料的操作角度來分,可以分為讀鎖和寫鎖。但是個人覺得,讀鎖和寫鎖是針對表鎖而言的,行鎖好像沒有這個區別。
行鎖:
可以參考我下一篇部落格:https://blog.csdn.net/tuesdayma/article/details/81910117
表鎖
概述: 表鎖主要正針對於myisam(mysql5.5之前預設儲存引擎)的儲存引擎而言的,每次對資料庫操作都會進行表鎖。
特點:
1、開銷小,加鎖快,無死鎖;發生鎖衝突的概率高,併發度很低。
2、讀鎖會阻塞其他session的寫,但是不會阻塞其他session的讀。
3、寫鎖會阻塞其他session的讀寫。
表上加讀鎖:
操作 | 當前session(加鎖的session) | 其他session |
---|---|---|
讀加鎖的表 | 能 | 能 |
讀其他表 | 不能(解鎖之後才能,加鎖的時候會報錯) | 能 |
寫加鎖的表 | 不能 | 會阻塞,但是鎖一旦釋放之後,就立刻執行 |
寫其他表 | 不能 | 能 |
表上加寫鎖:
操作 | 當前session(加鎖的session) | 其他session |
---|---|---|
讀加鎖的表 | 能 | 不能 |
讀其他表 | 不能(解鎖之後才能,加鎖的時候會報錯) | 能 |
寫加鎖的表 | 不能 | 會阻塞,但是鎖一旦釋放之後,就立刻執行 |
寫其他表 | 不能 | 能 |
注意: myisam的讀寫鎖排程是寫鎖比讀鎖優先。寫鎖後,其他執行緒不能對該表做任何操作,會阻塞在那邊,如果大量的更新操作會讓讀操作很難拿到鎖,嚴重的時候會使讀操作永久阻塞,這就是為什麼myisam不適合做大量寫操作業務資料庫的引擎。
演示:
1、準備工作: 建立一張儲存引擎為myisam的test02表。
2、關閉自動提交:
set autocommit=0;
show variables like 'autocommit';
3、給test02表加一個讀鎖
給test02表加一個讀鎖:lock table 表名 read(write);
檢視當前加鎖的表:show open tables where in_use>0;
4、結論1:表上加讀鎖,所有session都能查詢
5、結論2:表上加讀鎖,當前session無法對錶進行編輯(增刪改),其他session對錶進行編輯會阻塞(右邊阻塞了)
6、結論3:表上加讀鎖,當前session是無法操作其他表,其他session可以操作其他表
Table ‘test01’ was not locked with LOCK TABLES 從字面上的意思是test01不是被鎖的表,可以從兩個方面去考慮,是不是把test01也鎖了就能操作了,還是說當前鎖的不是test02而不是test01所以才不能操作。
補充:個人猜想,當前session只能鎖一張表,如果鎖了一張表之後又去鎖另一張表,會釋放前者,鎖後者。
7、表上加寫鎖: 在加鎖之前必須要保證其他session所有的編輯都提交了,不然會阻塞。
8、結論4:表上加寫鎖,當前session未編輯的時候,其他session是可以查詢的,但是當前session編輯之後未提交事務,其他session對鎖定的表進行操作就會阻塞,直到鎖被釋放之後才能操作出來。
9、結論5:表上加寫鎖,當前session可以對鎖定的表進行增刪改查,但是不能對其他表進行操作。
10、結論6:表上加寫鎖,當前session可以對鎖定的表進行編輯之後,不提交事務,然後直接釋放鎖,預設好像是直接提交了事務(開頭是將自動提交事務關閉的)。
11:分析表鎖定:show status like 'table%';
Table_locks_immediate:表示可以立即獲取鎖的查詢次數,每立即獲取鎖,這個值就加一。
Table_locks_waited:表示不能立即獲取鎖的次數,如果不能立即獲取所(即需要等待的話),這個值就加一。這個值往往是反應併發量的關鍵,如果值越大,則併發量越大(因為等待了很多次)。