日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

数据库中的行锁和表锁

發(fā)布時(shí)間:2025/5/22 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据库中的行锁和表锁 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一、事務(wù)并發(fā)調(diào)度的問題
  • 臟讀:A事務(wù)讀取B事務(wù)尚未提交的更改數(shù)據(jù),并在這個(gè)數(shù)據(jù)基礎(chǔ)上操作。如果B事務(wù)回滾,那么A事務(wù)讀到的數(shù)據(jù)根本不是合法的,稱為臟讀。在oracle中,由于有version控制,不會(huì)出現(xiàn)臟讀。
  • 不可重復(fù)讀:A事務(wù)讀取了B事務(wù)已經(jīng)提交的更改(或刪除)數(shù)據(jù)。比如A事務(wù)第一次讀取數(shù)據(jù),然后B事務(wù)更改該數(shù)據(jù)并提交,A事務(wù)再次讀取數(shù)據(jù),兩次讀取的數(shù)據(jù)不一樣。
  • 幻讀:A事務(wù)讀取了B事務(wù)已經(jīng)提交的新增數(shù)據(jù)。注意和不可重復(fù)讀的區(qū)別,這里是新增,不可重復(fù)讀是更改(或刪除)。這兩種情況對(duì)策是不一樣的,對(duì)于不可重復(fù)讀,只需要采取行級(jí)鎖防止該記錄數(shù)據(jù)被更改或刪除,然而對(duì)于幻讀必須加表級(jí)鎖,防止在這個(gè)表中新增一條數(shù)據(jù)。
  • 第一類丟失更新:A事務(wù)撤銷時(shí),把已提交的B事務(wù)的數(shù)據(jù)覆蓋掉。
  • 第二類丟失更新:A事務(wù)提交時(shí),把已提交的B事務(wù)的數(shù)據(jù)覆蓋掉。
  • 三級(jí)封鎖協(xié)議
  • 一級(jí)封鎖協(xié)議:事務(wù)T中如果對(duì)數(shù)據(jù)R有寫操作,必須在這個(gè)事務(wù)中對(duì)R的第一次讀操作前對(duì)它加X鎖,直到事務(wù)結(jié)束才釋放。事務(wù)結(jié)束包括正常結(jié)束(COMMIT)和非正常結(jié)束(ROLLBACK)。
  • 二級(jí)封鎖協(xié)議:一級(jí)封鎖協(xié)議加上事務(wù)T在讀取數(shù)據(jù)R之前必須先對(duì)其加S鎖,讀完后方可釋放S鎖。?
  • 三級(jí)封鎖協(xié)議?:一級(jí)封鎖協(xié)議加上事務(wù)T在讀取數(shù)據(jù)R之前必須先對(duì)其加S鎖,直到事務(wù)結(jié)束才釋放。
  • 可見,三級(jí)鎖操作一個(gè)比一個(gè)厲害(滿足高級(jí)鎖則一定滿足低級(jí)鎖)。但有個(gè)非常致命的地方,一級(jí)鎖協(xié)議就要在第一次讀加x鎖,直到事務(wù)結(jié)束。幾乎就要在整個(gè)事務(wù)加寫鎖了,效率非常低。三級(jí)封鎖協(xié)議只是一個(gè)理論上的東西,實(shí)際數(shù)據(jù)庫常用另一套方法來解決事務(wù)并發(fā)問題。 二、隔離性級(jí)別 mysql用意向鎖(另一種機(jī)制)來解決事務(wù)并發(fā)問題,為了區(qū)別封鎖協(xié)議,弄了一個(gè)新概念隔離性級(jí)別:包括Read Uncommitted、Read Committed、Repeatable Read、Serializable。mysql 一般默認(rèn)Repeatable Read。 總結(jié)一下,repeatable read能解決臟讀和不可重復(fù)讀,但不能解決丟失修改。 三、mysql的行鎖和表鎖 下面對(duì)行鎖和表鎖進(jìn)行一個(gè)簡(jiǎn)單的介紹。
    • 表級(jí)鎖:每次操作鎖住整張表。開銷小,加鎖快;不會(huì)出現(xiàn)死鎖;鎖定粒度大,發(fā)生鎖沖突的概率最高,并發(fā)度最低;
    • 行級(jí)鎖:每次操作鎖住一行數(shù)據(jù)。開銷大,加鎖慢;會(huì)出現(xiàn)死鎖;鎖定粒度最小,發(fā)生鎖沖突的概率最低,并發(fā)度也最高;
    • 頁面鎖:開銷和加鎖時(shí)間界于表鎖和行鎖之間;會(huì)出現(xiàn)死鎖;鎖定粒度界于表鎖和行鎖之間,并發(fā)度一般。
    1、MyISAM的鎖 稍微提一下MyISAM,只說和InnoDB不同的。 a. MyISAM只有表鎖,鎖又分為讀鎖和寫鎖。  b.?沒有事務(wù),不用考慮并發(fā)問題 c.?由于鎖的粒度太大,所以當(dāng)該表寫并發(fā)量較高時(shí),要等待的查詢就會(huì)很多了。 2、InnoDB的行鎖和表鎖 沒有特定的語法。mysql的行鎖是通過索引體現(xiàn)的。 如果where條件中只用到索引項(xiàng),則加的是行鎖;否則加的是表鎖。比如說主鍵索引,唯一索引和聚簇索引等。如果sql的where是全表掃描的,想加行鎖也愛莫能助。 行鎖和表鎖對(duì)我們編程的影響是要在where中盡量只用索引項(xiàng),否則就會(huì)觸發(fā)表鎖。 3、加鎖和解鎖 在InnoDB中,select,insert,update,delete等語句執(zhí)行時(shí)都會(huì)自動(dòng)加解鎖。select的鎖一般執(zhí)行完就釋放了,修改操作的X鎖會(huì)持有到事務(wù)結(jié)束,效率高很多。 mysql也給用戶提供了加鎖的機(jī)會(huì),只要在sql后加LOCK IN SHARE MODE 或FOR UPDATE 共享鎖(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE 排他鎖(X):SELECT * FROM table_name WHERE ... FOR UPDATE 值得注意的是,自己加的鎖沒有釋放鎖的語句,所以鎖會(huì)持有到事務(wù)結(jié)束。 四、解決丟失修改--樂觀鎖和悲觀鎖 加鎖就是為了解決丟失修改。如果一個(gè)事務(wù)中只有一句sql,數(shù)據(jù)庫是可以保證它是并發(fā)安全的。丟失修改的特征就是在一個(gè)事務(wù)中先讀P數(shù)據(jù),再寫P數(shù)據(jù)。所謂丟失修改,一般是A事務(wù)有兩個(gè)操作,后一個(gè)操作依賴于前一個(gè)操作,之后后一個(gè)操作覆蓋了B事務(wù)的寫操作。 如果一個(gè)事務(wù)先讀后寫同一份數(shù)據(jù),就可能發(fā)生丟失修改,要做一些處理。下面對(duì)樂觀鎖和悲觀鎖進(jìn)行一個(gè)簡(jiǎn)單的介紹。 悲觀鎖和樂觀鎖的概念: 悲觀鎖(Pessimistic Concurrency Control,PCC):假定會(huì)發(fā)生并發(fā)沖突,屏蔽一切可能違反數(shù)據(jù)完整性的操作。 樂觀鎖(Optimistic Concurrency Control,OCC):假設(shè)不會(huì)發(fā)生并發(fā)沖突,只在提交操作時(shí)檢查是否違反數(shù)據(jù)完整性。 樂觀鎖和悲觀鎖也不僅僅能用在數(shù)據(jù)庫中,也能用在線程中。 悲觀鎖的缺陷是不論是頁鎖還是行鎖,加鎖的時(shí)間可能會(huì)很長(zhǎng),這樣可能會(huì)長(zhǎng)時(shí)間的限制其他用戶的訪問,也就是說悲觀鎖的并發(fā)訪問性不好。 樂觀鎖不能解決臟讀,加鎖的時(shí)間要比悲觀鎖短(只是在執(zhí)行sql時(shí)加了基本的鎖保證隔離性級(jí)別),樂觀鎖可以用較大的鎖粒度獲得較好的并發(fā)訪問性能。但是如果第二個(gè)用戶恰好在第一個(gè)用戶提交更改之前讀取了該對(duì)象,那么當(dāng)他完成了自己的更改進(jìn)行提交時(shí),數(shù)據(jù)庫就會(huì)發(fā)現(xiàn)該對(duì)象已經(jīng)變化了,這樣,第二個(gè)用戶不得不重新讀取該對(duì)象并作出更改。 可見,樂觀鎖更適合解決沖突概率極小的情況;而悲觀鎖則適合解決并發(fā)競(jìng)爭(zhēng)激烈的情況,盡量用行鎖,縮小加鎖粒度,以提高并發(fā)處理能力,即便加行鎖的時(shí)間比加表鎖的要長(zhǎng)。 悲觀鎖的例子 這里僅僅提供一種解決丟失修改的悲觀鎖例子。丟失修改的特征就是在一個(gè)事務(wù)中先讀P數(shù)據(jù),再寫P數(shù)據(jù)。而且一級(jí)鎖協(xié)議能解決丟失修改,所以如果事務(wù)A 中寫P,我們只要在A中第一次讀P前加X鎖。 樂觀鎖的例子 樂觀鎖檢測(cè)并發(fā)沖突的常見的兩種做法:
  • 使用數(shù)據(jù)版本(Version)。在P數(shù)據(jù)上(通常每一行)加version字段(int),A事務(wù)在讀數(shù)據(jù)P 時(shí)同時(shí)讀出版本號(hào),在修改數(shù)據(jù)前檢測(cè)最新版本號(hào)是否等于先前取出的版本號(hào),如果是,則修改,同時(shí)把版本號(hào)+1;否則要么回滾,要么重新執(zhí)行事務(wù)。另外,數(shù)據(jù)P的所有修改操作都要把版本號(hào)+1。有一個(gè)非常重要的點(diǎn),版本號(hào)是用來查看被讀的變量有無變化,而不是針對(duì)被寫的變量,作用是防止被依賴的變量有修改。
  • 使用時(shí)間戳(TimeStamp)。做法類似于1中。
  • 總結(jié) 樂觀鎖更適合并發(fā)競(jìng)爭(zhēng)少的情況,最好隔那么3-5分鐘才有一次沖突。當(dāng)并發(fā)量為10時(shí)就能明顯感覺樂觀鎖更慢; 上面只是一讀一寫。考慮如果一個(gè)事務(wù)中有3個(gè)寫,如果每次寫都是九死一生,事務(wù)提交比較難,這時(shí)就更要考慮是不是要用樂觀鎖了。 但是,當(dāng)分布式數(shù)據(jù)庫規(guī)模大到一定程度后,又另說了。基于悲觀鎖的分布式鎖在集群大到一定程度后(從幾百臺(tái)擴(kuò)展到幾千臺(tái)時(shí)),性能開銷就打得無法接受。所以目前的趨勢(shì)是大規(guī)模的分布式數(shù)據(jù)庫更傾向于用樂觀鎖來達(dá)成external consistency。

    轉(zhuǎn)載于:https://www.cnblogs.com/Demrystv/p/9109325.html

    總結(jié)

    以上是生活随笔為你收集整理的数据库中的行锁和表锁的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。