数据库中的行锁和表锁
生活随笔
收集整理的這篇文章主要介紹了
数据库中的行锁和表锁
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、事務并發調度的問題 臟讀:A事務讀取B事務尚未提交的更改數據,并在這個數據基礎上操作。如果B事務回滾,那么A事務讀到的數據根本不是合法的,稱為臟讀。在oracle中,由于有version控制,不會出現臟讀。 不可重復讀:A事務讀取了B事務已經提交的更改(或刪除)數據。比如A事務第一次讀取數據,然后B事務更改該數據并提交,A事務再次讀取數據,兩次讀取的數據不一樣。 幻讀:A事務讀取了B事務已經提交的新增數據。注意和不可重復讀的區別,這里是新增,不可重復讀是更改(或刪除)。這兩種情況對策是不一樣的,對于不可重復讀,只需要采取行級鎖防止該記錄數據被更改或刪除,然而對于幻讀必須加表級鎖,防止在這個表中新增一條數據。 第一類丟失更新:A事務撤銷時,把已提交的B事務的數據覆蓋掉。 第二類丟失更新:A事務提交時,把已提交的B事務的數據覆蓋掉。 三級封鎖協議 一級封鎖協議:事務T中如果對數據R有寫操作,必須在這個事務中對R的第一次讀操作前對它加X鎖,直到事務結束才釋放。事務結束包括正常結束(COMMIT)和非正常結束(ROLLBACK)。 二級封鎖協議:一級封鎖協議加上事務T在讀取數據R之前必須先對其加S鎖,讀完后方可釋放S鎖。? 三級封鎖協議?:一級封鎖協議加上事務T在讀取數據R之前必須先對其加S鎖,直到事務結束才釋放。 可見,三級鎖操作一個比一個厲害(滿足高級鎖則一定滿足低級鎖)。但有個非常致命的地方,一級鎖協議就要在第一次讀加x鎖,直到事務結束。幾乎就要在整個事務加寫鎖了,效率非常低。三級封鎖協議只是一個理論上的東西,實際數據庫常用另一套方法來解決事務并發問題。 二、隔離性級別 mysql用意向鎖(另一種機制)來解決事務并發問題,為了區別封鎖協議,弄了一個新概念隔離性級別:包括Read Uncommitted、Read Committed、Repeatable Read、Serializable。mysql 一般默認Repeatable Read。 總結一下,repeatable read能解決臟讀和不可重復讀,但不能解決丟失修改。 三、mysql的行鎖和表鎖 下面對行鎖和表鎖進行一個簡單的介紹。 使用數據版本(Version)。在P數據上(通常每一行)加version字段(int),A事務在讀數據P 時同時讀出版本號,在修改數據前檢測最新版本號是否等于先前取出的版本號,如果是,則修改,同時把版本號+1;否則要么回滾,要么重新執行事務。另外,數據P的所有修改操作都要把版本號+1。有一個非常重要的點,版本號是用來查看被讀的變量有無變化,而不是針對被寫的變量,作用是防止被依賴的變量有修改。 使用時間戳(TimeStamp)。做法類似于1中。 總結 樂觀鎖更適合并發競爭少的情況,最好隔那么3-5分鐘才有一次沖突。當并發量為10時就能明顯感覺樂觀鎖更慢; 上面只是一讀一寫。考慮如果一個事務中有3個寫,如果每次寫都是九死一生,事務提交比較難,這時就更要考慮是不是要用樂觀鎖了。 但是,當分布式數據庫規模大到一定程度后,又另說了。基于悲觀鎖的分布式鎖在集群大到一定程度后(從幾百臺擴展到幾千臺時),性能開銷就打得無法接受。所以目前的趨勢是大規模的分布式數據庫更傾向于用樂觀鎖來達成external consistency。
- 表級鎖:每次操作鎖住整張表。開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖沖突的概率最高,并發度最低;
- 行級鎖:每次操作鎖住一行數據。開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖沖突的概率最低,并發度也最高;
- 頁面鎖:開銷和加鎖時間界于表鎖和行鎖之間;會出現死鎖;鎖定粒度界于表鎖和行鎖之間,并發度一般。
轉載于:https://www.cnblogs.com/Demrystv/p/9109325.html
總結
以上是生活随笔為你收集整理的数据库中的行锁和表锁的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python新手菜鸟之基础篇
- 下一篇: 五月最后一天