回覆列表
  • 1 # 隔壁松林

    在講鎖之前,首先講講兩個概念吧 ,嘿嘿 行鎖MySQL 事務屬性

    行鎖

    mysql實現行級鎖的兩大前提就是,innodb引擎並且開啟事務。由於MySQL/InnoDB的加鎖分析,一般日常中使用方式為: select .... from table where ..... for update 語句並且在 Repeatable Read 事務隔離級別下。

    行鎖的劣勢:開銷大;加鎖慢;會出現死鎖

    行鎖的優勢:鎖的粒度小,發生鎖衝突的機率低;處理併發的能力強

    加鎖的方式:自動加鎖。對於UPDATE、DELETE和INSERT語句,InnoDB會自動給涉及資料集加排他鎖;對於普通SELECT語句,InnoDB不會加任何鎖;當然我們也可以顯示的加鎖:

    共享鎖:select * from table where “條件” + lock in share more

    排他鎖:select * from table where ”條件“ + for update

    MySQL 事務屬性

    事務是由一組SQL語句組成的邏輯處理單元,事務具有ACID屬性。

    原子性(Atomicity):事務是一個原子操作單元。在當時原子是不可分割的最小元素,其對資料的修改,要麼全部成功,要麼全部都不成功。一致性(Consistent):事務開始到結束的時間段內,資料都必須保持一致狀態。隔離性(Isolation):資料庫系統提供一定的隔離機制,保證事務在不受外部併發操作影響的”獨立”環境執行。永續性(Durable):事務完成後,它對於資料的修改是永久性的,即使出現系統故障也能夠保持。舉例說明

    innodb引擎中行級鎖分為以下三種鎖

    1.Record Lock

    單個行記錄上的鎖

    2.Gap Lock

    間隙鎖,鎖定一個範圍,不包括記錄本身

    3.Next-Key Lock

    鎖定一個範圍和記錄本身

    話不多說直接程式碼開幹

    程式碼:select * from table where order_no= "20200521xxx" for update;

    order_no是主鍵的時候,可以確定唯一一條資料, 所以在此加上Record Lock(即為單個記錄上鎖)

    order_no是普通索引的時候,innodb層面 會根據條件鎖定一個範圍,在查詢的時候聚簇索引上加Record Lock(即為單個記錄上鎖)

    order_no不是索引的時候,本條sql會進行全表掃描,會在所有的聚簇索引上加鎖,相當於全表鎖,這個是在mysql innodb引擎層面決定。

    還有一種情況,假如後面跟多個情況

    程式碼:select * from table where order_no= "20200521" and code="xxx" for update;

    經過上面分析

    order_no主鍵,code不是索引,查詢都只有一條資料,加Record Lock

    order_no 普通索引,code不是索引 ,會先掃描order_no= "20200521",範圍下加鎖

    結論:我們的for update 並不時都鎖一條記錄,也並不是只有一個鎖,但是也包含我們常用的手段了,在專案中可以實踐用用哦

  • 中秋節和大豐收的關聯?
  • 什麼是司法獨立?