MySQL的鎖怎么解?

大家都知道java里面的synchronized,對象鎖。(這里不扯什么類鎖,對象鎖,類鎖其實(shí)就是Class對象的對象鎖)
A線程拿o對象的鎖之后,其他的線程訪問o對象的鎖都需等待。

那MySQL的表鎖就是針對于表的。(行鎖就是行的唄)

MySQL鎖是啥?

鎖顧名思義,解決因資源共享,而造成的并發(fā)問題。

1,表鎖

MyISAM 存儲引擎默認(rèn)為表鎖。不想解釋太多上例子大家都懂了。

第一個客戶端,為了好舉例子先開一個事務(wù),不然看不到效果,然后修改job表,修改完之后先不提交,看第二個客戶端。

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> update job set jobName= 'Java開發(fā)工程師' where jobName = 'Java開發(fā)工程師';
Query OK, 0 rows affected (0.28 sec)
Rows matched: 3872  Changed: 0  Warnings: 0

mysql>

第二個客戶端,依然修改這個表,一樣的執(zhí)行一個update語句,發(fā)現(xiàn)這個時候卡住不動了?
不要以為你dos卡了??,這個時候是你的第一個客戶端獲取了job 表的鎖,但是并沒有提交事務(wù)也就是沒有釋放鎖所導(dǎo)致的

mysql> update job set jobName = '.net工程師' where jobName = '.net工程師';
........等待中

那么接下來給一個客戶端commit 試試。

mysql> update job set jobName = '.net工程師' where jobName = '.net工程師';
Query OK, 0 rows affected (33.14 sec)
Rows matched: 1286  Changed: 0  Warnings: 0

這時候看到了吧,你的第一個客戶端一提交事務(wù),你的第二個客戶端馬上執(zhí)行成功了,這個時候就是你的第一個客戶端釋放鎖之后,第二個客戶端就拿到鎖去執(zhí)行語句啦,這樣就非常好理解啦。

2,行鎖

InnoDB 默認(rèn)使用行鎖,既然知道了表鎖,那么行鎖的概念也很好理解,粒度更加細(xì)的一個鎖。

行鎖的一個大前提需要知道的就是對于行的條件必須是索引列,如果不是索引列則上升為表鎖(劃重點(diǎn))

那么也舉一個例子同上
先是修改job 表的某條數(shù)據(jù),首先你的serialNo必須是索引列,否則會上升為表鎖

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> update job set serialNo = '116004626' where serialNo = '116004626';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1  Changed: 0  Warnings: 0
mysql>

繼續(xù)第二個客戶端看

mysql> update job set serialNo = '116004626' where serialNo = '116004627';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0

mysql>

這時候看,其實(shí)行鎖已經(jīng)生效了,因?yàn)槲业诙€客戶端和第一個客戶端修改的同一張表,但第二個客戶端并沒有進(jìn)入等待。
說明第一個客戶端只在 serialNo = '116004626' 這條記錄上加鎖了。

那么繼續(xù)看如果我們在第二個客戶端繼續(xù)修改serialNo = '116004626' 這條記錄,會怎么樣?

mysql> update job set serialNo = '116004626' where serialNo = '116004626';
........等待中

可以看到情況跟上面表鎖是一樣的。進(jìn)入等待了,這時候我們依然繼續(xù)commit第一個客戶端的事務(wù)

mysql> update job set serialNo = '116004626' where serialNo = '116004626';
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
mysql> update job set serialNo = '116004626' where serialNo = '116004626';
Query OK, 0 rows affected (0.00 sec)

??不好意思超時了,重新執(zhí)行一下可以看到成功了,雖然超時了但是也是在commit 之后出現(xiàn)的,只要第一個客戶端的事務(wù)不提交那么其他客戶端對這條數(shù)據(jù)的寫操作都會進(jìn)行等待。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容