資料庫是如何使用鎖

mousycoder發表於2016-02-22
  • 悲觀鎖
    資料庫的鎖通常都是頁級鎖,就是對同一張表裡的資料採用序列化的更新插入機制,在任何時間同一張表只能插入一條資料,別的想插入的資料必須要等這條資料插完之後才能依次插入。結果是效能降低,頻繁操作的時候,會假死,Oracle 是行級鎖,oracle 悲觀鎖,分為:for update 和 for update nowait

  • 樂觀鎖
    一開始假設不會造成衝突,提交的時候再進行資料衝突檢測。

  1. 資料取得時候,把整個資料都copy到應用中,提交的時候比對當前資料庫中的資料和開始的時候取得的資料,如果兩個資料一模一樣,就表示沒有衝突可以提交,否則是併發衝突,則需要業務邏輯解決

  2. 版本戳,在樂觀鎖的資料庫table上建立一個新的column,型別為number,資料每次更新一次的時候,版本數就會加1.如果有2個session同樣的對某條資料進行操作,兩者都取得的版本號為1,當第一個session進行資料更新後,在提交的時候檢視到當前的資料庫版本還是為1,和一開始取得的版本相同,則提交,第二個session也更新了資料提交,發現資料庫版本為2,和一開始取得的版本號為1不一致,則知道別人已經更新過此條記錄,這個時候再進行業務處理,比如整個transaction都rollback,在驗證版本戳的時候,可以用應用程式或者trigger(開銷比較大)

  3. 和2類似,只不過是比較時間戳

  • 死鎖

  1. 事務A取得資料列1的共享鎖定

  2. 事務B取得資料列2的共享鎖定

  3. 事務A現在要求資料列2的獨佔鎖定,但會被阻塞到事務B完成並且釋放出資料列2的共享鎖定為止

  4. 事務B現在要求資料列1的獨佔鎖定,單會被阻塞到事務A完成並且釋放出資料列1的共享鎖定為止

等到事務B完成後,事務A才能完成,但是事務B又被事務A封閉了,這種情況叫迴圈相依性,事務A相依於事務B,並且事務B相依於事務B,從而封閉了這個迴圈

InnoDB解決死鎖的方式是讓最少X鎖的事務回滾。

相關文章