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

MySQL

MySQL(InnoDB存儲引擎)默認是自動提交事務的,因此這個測試,須要先將MySQL的autocommit設置爲0,關閉自動提交,須要本身手動提交事務session

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

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

行鎖

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

這個時候是沒有任何結果的,由於t_card表已經加鎖了(這個時候其實加的是行鎖),因此cardid=‘1’ 這一行的其餘加鎖操做是無效的3d

可是不加鎖查詢這一條記錄倒是能夠的code

也就是說雖然這一條記錄所在的行被鎖定了,可是並不影響咱們正常的查詢,固然了針對這一行的DML操做也是無效的blog

那若是咱們對除了cardid=‘1’ 的其餘行操做會怎樣呢?事務

對於其餘的行DML是徹底沒問題的,因此我在前面才說這是行鎖,由於只有咱們的cardid=‘1’的行被鎖了博客

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

提交事務以後,另外一邊的加鎖SQL纔會生效io

表鎖

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

沒錯,咱們不根據主鍵查詢,而是查詢全部的記錄,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'; 
相關文章
相關標籤/搜索