MySQL鎖型別以及子查詢鎖表問題 解鎖

2022-08-18 00:36:12 字數 2070 閱讀 2099

mysql中select * for update鎖表的範圍

mysql中select * for update鎖表的問題

由於innodb預設是row-level lock,所以只有「明確」的指定主鍵,mysql才會執行row lock (只鎖住被選取的資料例) ,否則mysql將會執行table

lock (將整個資料表單給鎖住)。 舉個例子: 假設有個表單products ,裡面有id跟name二個字段,id是主鍵。

例1: (明確指定主鍵,並且有此筆資料,row lock)

select * from products where id='3' for update;

select * from products where id='3' and type=1 for update;

例2: (明確指定主鍵,若查無此筆資料,無lock)

select * from products where id='-1' for update;

例2: (無主鍵,table lock)

select * from products where name='mouse' for update;

例3: (主鍵不明確,table lock)

select * from products where id<>'3' for update;

例4: (主鍵不明確,table lock)

select * from products where id like '3' for update;

注1: for update僅適用於innodb,且必須在交易區塊(begin/commit)中才能生效。

注2: 要測試鎖定的狀況,可以利用mysql的command mode ,開二個視窗來做測試。

在mysql 5.0中測試確實是這樣的

另外:myasim 只支援表級鎖,innerdb支援行級鎖 新增了(行級鎖/表級鎖)鎖的資料不能被其它事務再鎖定,也不被其它事務修改

(修改、刪除) 。是表級鎖時,不管是否查詢到記錄,都會鎖定表。

今天碰到詭異的表死鎖問題。

首先tomcat報錯:

caused by: com.mysql.jdbc.exceptions.jdbc4.mysqltransactionrollbackexception: deadlock found when trying to get lock; try restarting transaction

at sun.reflect.nativeconstructoraccessorimpl.newinstance0(native method)

使用 show engine innodb status .

檢視mysql死鎖。

發現是 update語句中把子查詢中的表給死鎖了。比如

update table_a set comments = (select count(1) from table_b where id = table_a.id) where id = 123;

把table_b給鎖住了。

搜尋了乙個,發現是mysql的問題。

最後發現這個不是mysql bug,

mysql 預設的隔離級別是repeatable-read,oracle預設資料隔離級別是 read-committed 。所以在mysq中

update ... select * from

insert into .... select * from

這些語句中,都會鎖住子表的row.

將mysql 隔離級別改成

set session transaction isolation level read committed;

問題就解決了。

解鎖第一種

show processlist;

找到鎖程序,kill id ;

第二種mysql>unlock tables;

鎖表鎖定資料表,避免在備份過程中,表被更新

mysql>lock tables tbl_name read;

為表增加乙個寫鎖定:

mysql>lock tables tbl_name write;

以上文章非原創,只做收藏用。

mysql子查詢鎖

session 1 mysql begin query ok,0 rows affected 0.00 sec mysql update a set name select name from bai where a.id bai.id where id 1 query ok,0 rows affe...

MySQL 全域性鎖 表鎖以及行鎖

mysql 5.7.25 ubuntu 16.04 全域性鎖即對整個資料庫例項加鎖,使得整個庫處於唯讀狀態,會阻塞dml和ddl語句。使用如下命令 簡稱ftwrl 可為資料庫加全域性鎖 flush tables with read lock 釋放全域性鎖命令如下 unlock tables 此外,在...

mysql 查詢鎖 MySQL 鎖查詢

一 從檢視檢視 檢視程序 show processlist 檢視是否鎖表 show open tables where in use 0 1 檢視當前的事務 select from information schema.innodb trx 2 檢視當前鎖定的事務 select from infor...