鎖:計算機協調多個進程或線程并發訪問某一資源的機制。
在數據庫中,除傳統的計算資源(如CPU、RAM、I/O等)的爭用外,數據也是一種供許多用戶共享的資源。如何保證數據并發的一致性、有效性是所有數據庫必須解決的一個問題,鎖沖突也是影響數據庫并發訪問性能的一個重要因素。從這個角度來說,鎖對數據庫而言顯得尤為重要,也更復雜。
鎖的分類
1)從對數據操作的類型分為讀鎖和寫鎖
2)從對數據操作的粒度分主要有表鎖和行鎖
讀鎖和寫鎖:
讀鎖(共享鎖):針對同一份數據,多個讀操作可以同時進行而不會互相影響。
寫鎖(排他鎖):當前寫操作沒有完成前,它會阻斷其他讀和寫操作。
表鎖
先看一些命令
我們可以手動對一張表加鎖,可以是讀鎖或者寫鎖,命令:
lock table 表名 read/write,表名 read/write,……
查看表有沒有鎖的命令
show open tables;

In_use的值是0代表沒鎖,是1代表有鎖。
現在數據庫中有一張表,test_lock,現在手動給它加鎖,進行一些操作測試。
一、加讀鎖
lock table test_lock read;

加鎖成功,可以用show open tables命令查看

現在可以做一些操作。
1、讀被鎖的表:
select * from test_lock;
在當前連接中:

可以查詢到結果。
在新連接中:

新的連接同樣可以查詢被鎖的表。
2、查詢庫中其他表:
select * from test2;
在當前連接中:

結果報錯,無法查詢。
在新連接中:

正常,沒有影響。
3、更新被鎖的表:
update test_lock set name = 'abcd' where id = '1';
在當前連接中:

無法更新。
在新連接中:
執行此語句后,會發現一直在等待,即阻塞了,直到我們把表的鎖釋放。
釋放鎖命令:unlock table;
執行釋放命令后,新連接中的update語句也馬上有了反應,

執行等待了1分多鐘。
4、更新庫中其他表:
update test2 set name = 'a2' where id = '1';
在當前連接中:

無法更新
在新連接中:

在新的會話中,更新其他表是沒有影響的。
二、加寫鎖
lock table test_lock write;

同樣,我們在當前會話和和新會話中做一些操作對比。
1、讀被鎖的表:
select * from test_lock;
當前會話中:

讀沒有影響。
新的會話中:
此時會被阻塞,需要等待釋放鎖。

2、查詢庫中其他表:
select * from test2;
當前會話中:

其他表不能查詢。
新的會話中:

此時不受影響。
3、更新被鎖的表:
update test_lock set name = 'abcd' where id = '2';
當前會話中:

可以更新。
新的會話中:
結果是被阻塞。
4、更新庫中其他表
update test2 set name = 'a2' where id = '2';
當前會話中:

此時不可以更新其他表。
新的會話中:

更新其他表時候沒有問題。
以上是對表分別加讀鎖和寫鎖,然后進行的一些操作對比,重要的關注在其他會話中對被鎖表的讀寫請求。
對表加讀鎖,不會阻塞其他進行對同一表的讀請求,但會阻塞對同一表的寫請求。只有當讀鎖釋放后,才會執行其他執行進行的寫操作。
對表加寫鎖,會阻塞其他進程對同一表的讀和寫的請求,只有當寫鎖釋放后,才會執行其它進程的讀寫操作。