bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

mysql行級鎖怎么使用 mysql行鎖和表鎖怎么實現

MYSQL行級鎖使用方法

當 web 日志中出現行鎖超時錯誤后,很多開發都會找我來排查問題,這里說下問題定位的難點!

創新互聯建站專業提供成都主機托管四川主機托管成都服務器托管四川服務器托管,支持按月付款!我們的承諾:貴族品質、平民價格,機房位于中國電信/網通/移動機房,BGP機房服務器托管服務有保障!

1. MySQL 本身不會主動記錄行鎖等待的相關信息,所以無法有效的進行事后分析。

2. 鎖爭用原因有多種,很難在事后判斷到底是哪一類問題場景,尤其是事后無法復現問題的時候。

3. 找到問題 SQL 后,開發無法有效從代碼中挖掘出完整的事務,這也和公司框架-產品-項目的架構有關,需要靠 DBA 事后采集完整的事務 SQL 才可以進行分析。

MySQL - for update 行鎖 表鎖

for update 的作用是在查詢的時候為行加上排它鎖,當一個事務的操作未完成時候,其他事務可以讀取但是不能寫入或更新。

它的典型使用場景是 高并發并且對于數據的準確性有很高要求 ,比如金錢、庫存等,一般這種操作都是很長一串并且開啟事務的,假如現在要對庫存進行操作,在剛開始讀的時候是1,然后馬上另外一個進程將庫存更新為0了,但事務還沒結束,會一直用1進行后續的邏輯,就會有問題,所以需要用for upate 加鎖防止出錯。

行鎖的具體實現算法有三種:record lock、gap lock以及next-key lock。

只在可重復讀或以上隔離級別下的特定操作才會取得 gap lock 或 next-key lock,在 Select、Update 和 Delete 時,除了基于唯一索引的查詢之外,其它索引查詢時都會獲取 gap lock 或 next-key lock,即鎖住其掃描的范圍。主鍵索引也屬于唯一索引,所以主鍵索引是不會使用 gap lock 或 next-key lock

for update 僅適用于InnoDB,并且必須開啟事務,在begin與commit之間才生效。

select 語句默認不獲取任何鎖,所以是可以讀被其它事務持有排它鎖的數據的!

InnoDB 既實現了行鎖,也實現了表鎖。

當有明確指定的主鍵/索引時候,是行級鎖,否則是表級鎖

假設表 user,存在有id跟name字段,id是主鍵,有5條數據。

明確指定主鍵,并且有此記錄,行級鎖

無主鍵/索引,表級鎖

主鍵/索引不明確,表級鎖

明確指定主鍵/索引,若查無此記錄,無鎖

參考博文:

巧用MySQL InnoDB引擎鎖機制解決死鎖問題[2]

索引 KEY_TSKTASK_MONTIME (STATUS_ID MON_TIME)

分析 涉及的兩條語句應該不會涉及相同的TSK_TASK記錄 那為什么會造成死鎖呢?

查詢MySQL官網文檔 發現這跟MySQL的索引機制有關 MySQL的InnoDB引擎是行級鎖 我原來的理解是直接對記錄進行鎖定 實際上并不是這樣的

要點如下:

不是對記錄進行鎖定 而是對索引進行鎖定

在UPDATE DELETE操作時 MySQL不僅鎖定WHERE條件掃描過的所有索引記錄 而且會鎖定相鄰的鍵值 即所謂的next key locking

如語句UPDATE TSK_TASK SET UPDATE_TIME = NOW() WHERE ID 會鎖定所有主鍵大于等于 的所有記錄 在該語句完成之前 你就不能對主鍵等于 的記錄進行操作

當非簇索引(non cluster index)記錄被鎖定時 相關的簇索引(cluster index)記錄也需要被鎖定才能完成相應的操作

再分析一下發生問題的兩條SQL語句 就不難找到問題所在了

當 update TSK_TASK set STATUS_ID= UPDATE_TIME=now () where STATUS_ID= and MON_TIME

假設 update TSK_TASK set STATUS_ID= UPDATE_TIME=now () where ID in ( ) 幾乎同時執行時 本語句首先鎖定簇索引(主鍵) 由于需要更新STATUS_ID的值 所以還需要鎖定KEY_TSKTASK_MONTIME 的某些索引記錄

這樣第一條語句鎖定了KEY_TSKTASK_MONTIME 的記錄 等待主鍵索引 而第二條語句則鎖定了主鍵索引記錄 而等待KEY_TSKTASK_MONTIME 的記錄 在此情況下 死鎖就產生了

筆者通過拆分第一條語句解決死鎖問題

先查出符合條件的ID select ID from TSK_TASK where STATUS_ID= and MON_TIME date_sub(now() INTERVAL minute) 然后再更新狀態 update TSK_TASK set STATUS_ID= where ID in (… )

至此 死鎖問題徹底解決

lishixinzhi/Article/program/MySQL/201311/29601

名稱欄目:mysql行級鎖怎么使用 mysql行鎖和表鎖怎么實現
網址分享:http://vcdvsql.cn/article48/ddcedhp.html

成都網站建設公司_創新互聯,為您提供動態網站品牌網站設計小程序開發網站設計公司域名注冊

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

外貿網站制作