1. 程式人生 > >關於數據庫行鎖與表鎖的認識

關於數據庫行鎖與表鎖的認識

soft 這不 class 查詢 才會 where 自動提交 height 開啟

MySQL

MySQL(InnoDB存儲引擎)默認是自動提交事務的,所以這個測試,需要先將MySQL的autocommit設置為0,關閉自動提交,需要自己手動提交事務

-- 關閉自動提交
set autocommit=0;
-- 開啟事務
begin;

這裏我主要針對的是悲觀鎖,其實也就是行鎖和表鎖,SQL 加上 FOR UPDATE 即可

技術分享圖片

行鎖

這個時候,我們再開啟一個客戶端訪問MySQL,輸入同一條加鎖的SQL查詢

技術分享圖片

這個時候是沒有任何結果的,因為t_card表已經加鎖了(這個時候其實加的是行鎖),所以cardid=‘1’ 這一行的其他加鎖操作是無效的

但是不加鎖查詢這一條記錄卻是可以的

技術分享圖片

也就是說雖然這一條記錄所在的行被鎖定了,但是並不影響我們正常的查詢,當然了針對這一行的DML操作也是無效的

技術分享圖片

技術分享圖片

那如果我們對除了cardid=‘1’ 的其他行操作會怎樣呢?

技術分享圖片

對於其他的行DML是完全沒問題的,所以我在前面才說這是行鎖,因為只有我們的cardid=‘1’的行被鎖了

好吧,我們放過cardid=‘1’這一行吧

技術分享圖片

提交事務之後,另一邊的加鎖SQL才會生效

表鎖

上面我們測試的只是行鎖,那表鎖,或者說怎樣才會發生表鎖?

技術分享圖片

沒錯,我們不根據主鍵查詢,而是查詢所有的記錄,MySQL就對整張表加鎖了,這不就是表鎖了嘛。對於這張表的任何記錄進行DML都是無效的

技術分享圖片

同時我們對於這張表的任何行進行加鎖SQL操作是無效的,那普通的SQL查詢又怎樣呢?

技術分享圖片

還好,這不妨礙我們的普通查詢,畢竟查詢是與鎖這東西沒什麽緣分的

結論

只要有鎖存在的地方(無論是一行還是整張表),我們對有鎖的地方進行任何加鎖SQL都是無效的,當然了DML也是無效的;但是我們的普通查詢是沒有問題的,同時對於沒有鎖的行也是可以進行DML操作的

至於如何解除鎖,可以查看這篇博客: https://zhengdl126.iteye.com/blog/1570865 。最後記得把MySQL的autocommit = 1

Oracle

Oracle是需要我們手動提交事務的,所以,我們不需要任何設置即可測試

技術分享圖片

只有提交事務之後,另一邊才會生效,同樣的普通查詢是沒有問題的。如果不根據主鍵查詢,就會鎖整張表。最後的結論是與MySQL一致的

查看哪張表被鎖以及解鎖

-- 查看哪張表被鎖
SELECT object_name, machine, s.sid, s.serial#, logon_time, locked_mode
FROM gv$locked_object l, dba_objects o, gv$session s 
WHERE l.object_id = o.object_id 
AND l.session_id = s.sid;

-- 解鎖(根據上邊SQL查詢結果得到sid和serial#)
--alter system kill session ‘sid,serial#‘; 
ALTER system kill session ‘23,1647‘; 

關於數據庫行鎖與表鎖的認識