日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

 

 

上一篇MySQL的文章講了事務(wù)的特性和原理(

最詳細(xì)的MySQL事務(wù)特性及原理講解!(一)

) 作為基礎(chǔ),小伙伴們自行查看。

關(guān)于MySQL隔離級別的講解,網(wǎng)上已經(jīng)很多了。和大家一樣,我也看過很多很多,但是發(fā)現(xiàn)看完之后還是暈暈乎乎,學(xué)習(xí)走了很多彎路。事務(wù)特性的原理是什么?什么隔離級別可以解決什么問題?具體什么原理?這些似乎都沒有講清楚,無非是抄來抄取,甚至都抄錯(cuò)了,我查了近10篇文章每篇都有各種各樣的錯(cuò)誤!比如下面這個(gè)舉例:

最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 

作者說RR解決了幻讀的問題,并且還不止一個(gè)人這樣說。還有說未提交讀級別下不加鎖。

最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 

那么事實(shí)是這樣嗎?(閱讀提醒:點(diǎn)收藏前先點(diǎn)「在看」,記憶效果翻倍!)

隔離性

與原子性、持久性側(cè)重于研究事務(wù)本身不同,隔離性研究的是不同事務(wù)之間的相互影響。隔離性是指,事務(wù)內(nèi)部的操作與其他事務(wù)是隔離的,并發(fā)執(zhí)行的各個(gè)事務(wù)之間不能互相干擾。

嚴(yán)格的隔離性,對應(yīng)了事務(wù)隔離級別中的Serializable (可串行化),但實(shí)際應(yīng)用中出于性能方面的考慮很少會(huì)使用可串行化。隔離性追求的是并發(fā)情形下事務(wù)之間互不干擾。SQL標(biāo)準(zhǔn)定義了4類隔離級別:Read Uncommitted(讀取未提交內(nèi)容)、Read Committed(讀取提交內(nèi)容)、Repeatable Read(可重讀)、Serializable(可串行化)。

對于隔離性的探討,主要可以分為兩個(gè)方面:

1.鎖機(jī)制保證隔離性

2.MVCC保證隔離性。

隔離級別原理及問題

嚴(yán)格的隔離性,對應(yīng)了事務(wù)隔離級別中的Serializable (可串行化),但實(shí)際應(yīng)用中出于性能方面的考慮很少會(huì)使用可串行化。所以,共有四種隔離級別來對應(yīng)不同的業(yè)務(wù)性能需求。然而正是由于不同的隔離級別,便產(chǎn)生了不同的問題。

我們不妨帶著幾個(gè)問題去繼續(xù)閱讀:

1.可重復(fù)讀和幻讀的區(qū)別是什么?

2.每個(gè)隔離級別解決了怎樣的問題?怎么解決的?

1、讀未提交(READ_UNCOMMITTED)

顧名思義,該隔離級別下可以讀取到另一個(gè)事務(wù)未提交的數(shù)據(jù)。嚴(yán)謹(jǐn)一點(diǎn),我們給出官方定義:

The isolation level that provides the least amount of protection between transactions. Queries employ a locking strategy that allows them to proceed in situations where they would normally wait for another transaction. However, this extra performance comes at the cost of less reliable results, including data that has been changed by other transactions and not committed yet (known as dirty read). Use this isolation level with great caution, and be aware that the results might not be consistent or reproducible, depending on what other transactions are doing at the same time. Typically, transactions with this isolation level only do queries, not insert, update, or delete operations.

如文檔所說,它提供了最低的隔離級別,查詢時(shí)采用無需等待其他事務(wù)的鎖策略。所以,在這個(gè)隔離級別下,基本上什么問題都會(huì)產(chǎn)生了。于是文檔建議,通常具有此隔離級別的事務(wù)僅執(zhí)行查詢,而不執(zhí)行插入,更新或刪除操作。

但是,這并不代表他一無是處。其實(shí)RU隔離級別解決了一個(gè)問題——當(dāng)A事務(wù)修改數(shù)據(jù)n,B事務(wù)也修改數(shù)據(jù)n,后執(zhí)行的語句會(huì)把另一個(gè)事務(wù)的結(jié)果覆蓋。如文章開頭提到的反例,如果讀未提交隔離級別下不加鎖,這是不可能實(shí)現(xiàn)的。

為了解決丟失修改的寫覆蓋問題,未提交讀規(guī)定:

1.事務(wù)A對當(dāng)前被讀取的數(shù)據(jù)不加鎖,事務(wù)B讀取也不加鎖。

2.事務(wù)A開始更新一行數(shù)據(jù)時(shí),必須先對其加排他鎖,直到事務(wù)結(jié)束才釋放。

如何證明呢?

事務(wù)A事務(wù)B

最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 


最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 


最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 


最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 


最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 

發(fā)生臟讀 和 等待

最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 

圖中左邊為事務(wù)A,右邊為事務(wù)B,可見事務(wù)A更新時(shí)加排他鎖,事務(wù)未提交,所以事務(wù)B更新數(shù)據(jù)發(fā)生阻塞。但是B卻可以讀取到A修改后的數(shù)據(jù),說明B在讀取時(shí)并未加任何鎖。

最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 

如圖,證明兩個(gè)事務(wù)在更新時(shí)發(fā)生了排他鎖競爭。

臟讀(DIRTY READ)

那么未提交讀會(huì)產(chǎn)生什么問題?剛才的例子依舊說明了,發(fā)生了臟讀。如圖:

最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 

右邊事務(wù)讀取到了左邊事務(wù)更改后的數(shù)據(jù) a=11,但左邊事務(wù)還未提交。

我們依舊給出臟讀的定義:

An operation that retrieves unreliable data, data that was updated by another transaction but not yet committed. It is only possible with the isolation level known as read uncommitted.

檢索不可靠數(shù)據(jù)的操作,該數(shù)據(jù)是由另一個(gè)事務(wù)更新但尚未提交的數(shù)據(jù)。只有在隔離級別稱為未提交讀的情況下才有可能。

劃重點(diǎn)!讀出來的數(shù)據(jù)不可靠,是可以被其他事務(wù)修改后未提交的數(shù)據(jù)。臟讀只可能出現(xiàn)在未提交讀情況下。

2、讀已提交(READ_COMMITTED)

讀已提交和讀未提交最大的區(qū)別如名字所說,可以讀到另一個(gè)事務(wù)已提交讀數(shù)據(jù)。官方定義如下:

An isolation level that uses a locking strategy that relaxes some of the protection between transactions, in the interest of performance. Transactions cannot see uncommitted data from other transactions, but they can see data that is committed by another transaction after the current transaction started. Thus, a transaction never sees any bad data, but the data that it does see may depend to some extent on the timing of other transactions.

事務(wù)無法看到來自其他事務(wù)的未提交的數(shù)據(jù),但是它們可以看到在當(dāng)前事務(wù)開始后另一個(gè)事務(wù)提交的數(shù)據(jù)。因此,一個(gè)事務(wù)永遠(yuǎn)不會(huì)看到任何不良數(shù)據(jù),但是它所看到的數(shù)據(jù)可能在某種程度上取決于其他事務(wù)的時(shí)間安排。

實(shí)驗(yàn)前,更改數(shù)據(jù)庫隔離級別為RC。

mysql> set session transaction isolation level read committed;Query OK, 0 rows affected (0.01 sec)
mysql> SELECT @@tx_isolation;+----------------+| @@tx_isolation |+----------------+| READ-COMMITTED |+----------------+1 row in set, 1 warning (0.00 sec)

事務(wù)A
事務(wù)B

最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 


最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 


最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 


最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 

臟讀被解決

最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 


最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 


最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 

不可重復(fù)讀出現(xiàn)

如上表AB事務(wù)可知,在B事務(wù)更改數(shù)據(jù) a=11 且事務(wù)未提交時(shí),A事務(wù)讀取到的還是舊數(shù)據(jù) a=9,可見RC隔離級別很好的解決了臟讀的問題。

但是緊接著在B事務(wù)提交后,A事務(wù)再次讀取數(shù)據(jù),a=11。在同一事務(wù)中兩次查詢出現(xiàn)了結(jié)果不一樣的情況,這就是不可重復(fù)讀。官方定義:

non-repeatable read:The situation when a query retrieves data, and a later query within the same transaction retrieves what should be the same data, but the queries return different results (changed by another transaction committing in the meantime).

查詢檢索數(shù)據(jù),而同一事務(wù)中的前后查詢檢索應(yīng)為相同的數(shù)據(jù),但實(shí)際查詢返回不同的結(jié)果(數(shù)據(jù)同時(shí)被其他提交的事務(wù)更改)。

很關(guān)鍵的一點(diǎn),不可重復(fù)讀是同一事務(wù)前后同樣的查詢返回了不同的數(shù)據(jù)!一定有人有這樣的疑惑,那臟讀不也是前后不一致嗎,怎么區(qū)分這兩者?很多文章只甩出了幾個(gè)臟讀、不可重復(fù)讀、幻讀的例子,卻并沒有解釋清楚到底什么是什么。

現(xiàn)在我可以肯定的說,臟讀的條件不可重復(fù)讀一定滿足,但是如果是不可重復(fù)讀,臟讀卻不一定滿足,臟讀屬于不可重復(fù)讀。可以這么理解,RC級別下,相當(dāng)于只解決了一部分不可重復(fù)讀的問題。

他是如何解決臟讀的呢,鎖機(jī)制:

1.事務(wù)A對當(dāng)前被讀取的數(shù)據(jù)加共享鎖,一旦讀完該行,立即釋放該共享鎖(注意是讀完立即釋放

2.事務(wù)A在更新某行數(shù)據(jù)時(shí),必須對其加上排他鎖,直到事務(wù)結(jié)束才釋放(注意是事務(wù)結(jié)束才釋放

 

3、可重復(fù)讀(REPEATABLE_READ)

聽起來,可重復(fù)讀解決了不可重復(fù)讀的問題。事實(shí)是這樣。官方定義:

The default isolation level for InnoDB. It prevents any rows that are queried from being changed by other transactions, thus blocking non-repeatable reads but not phantom reads. It uses a moderately strict locking strategy so that all queries within a transaction see data from the same snapshot, that is, the data as it was at the time the transaction started.

InnoDB的默認(rèn)隔離級別它可防止查詢的任何行被其他事務(wù)更改,從而阻止不可重復(fù)的讀取,但不會(huì)阻止幻讀。它使用中等嚴(yán)格的鎖定策略,以便事務(wù)中的所有查詢都可以查看來自同一快照的數(shù)據(jù),即事務(wù)開始時(shí)的數(shù)據(jù)。

看重點(diǎn)!RR隔離級別是InnoDB默認(rèn)隔離級別,他可以解決不可重復(fù)讀,但不能解決幻讀!這就是為什么我說很多文章錯(cuò)了,官方已經(jīng)給出了明確定義。

mysql> set session transaction isolation level repeatable read;Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @@tx_isolation;+-----------------+| @@tx_isolation  |+-----------------+| REPEATABLE-READ |+-----------------+1 row in set, 1 warning (0.00 sec)

如表格所示,不可重復(fù)讀是被解決了,但很明顯還有一個(gè)問題,沒有解決幻讀。

事務(wù)A事務(wù)B

最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 


最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 


最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 


最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 

已解決不可重復(fù)讀
此時(shí)我們再來一次,回到B事務(wù)提交前但狀態(tài),執(zhí)行一條insert語句。

最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 


最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 

回到更新前狀態(tài)。
在B事務(wù)執(zhí)行 insert 后再次查詢

最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 


最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 

B事務(wù)提交后出現(xiàn)了奇怪的情況。A事務(wù)查詢到的數(shù)據(jù)前后一致,但是在UPDATE條件下符合的數(shù)據(jù)卻變成兩條。

最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 

A row that Appears in the result set of a query, but not in the result set of an earlier query. For example, if a query is run twice within a transaction, and in the meantime, another transaction commits after inserting a new row or updating a row so that it matches the WHERE clause of the query.

在查詢的結(jié)果集中出現(xiàn)的行,但在較早的查詢的結(jié)果集中沒有出現(xiàn)。例如,如果一個(gè)查詢在一個(gè)事務(wù)中運(yùn)行兩次,同時(shí),另一個(gè)事務(wù)將在插入新行或更新一行以使其與查詢的WHERE子句匹配之后提交。

請看上方幻讀定義。重點(diǎn)是,同樣的條件同一事務(wù)前后結(jié)果中出現(xiàn)了和之前不一樣的行。與不可重復(fù)讀的區(qū)別是什么:幻讀的條件也符合不可重復(fù)讀,但是不可重復(fù)讀不一定符合幻讀。前后檢索出不一樣的行當(dāng)然查詢前后查詢結(jié)果不同,但是查詢結(jié)果不同不一定有新的行。

為什么很多文章錯(cuò)誤的認(rèn)為RR可以解決幻讀呢?我也不知道,可能是被快照讀迷惑了?MVCC能解決快照讀下的幻讀問題,但是沒法保證當(dāng)前讀下的幻讀問題(這個(gè)我們下一篇細(xì)說,內(nèi)容太多了)。但是幻讀確實(shí)在一定條件下解決,這個(gè)條件就是 next-key locks。

By default, InnoDB operates in REPEATABLE READ transaction isolation level. In this case, InnoDB uses next-key locks for searches and index scans, which prevents phantom rows

默認(rèn)情況下,InnoDB以REPEATABLE READ事務(wù)隔離級別運(yùn)行。在這種情況下,InnoDB使用next-key locks 鎖定進(jìn)行搜索和索引掃描,從而防止幻讀

使用效果如下:

select count(*) from test where id>=9 lock in share mode;

最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 

執(zhí)行 insert 發(fā)生阻塞,如此便使用了 next-key locks 防止幻讀。

鎖原理:

1.事務(wù)A在讀取某數(shù)據(jù)時(shí),必須先對其加共享鎖,直到事務(wù)結(jié)束才釋放(注意是事務(wù)結(jié)束才釋放)

2.事務(wù)A在更新某數(shù)據(jù)時(shí),必須先對其加排他鎖,直到事務(wù)結(jié)束才釋放(注意是事務(wù)結(jié)束才釋放)

 

4、串行讀(SERIALIZABLE_READ)

The isolation level that uses the most conservative locking strategy, to prevent any other transactions from inserting or changing data that was read by this transaction, until it is finished. This way, the same query can be run over and over within a transaction, and be certain to retrieve the same set of results each time. Any attempt to change data that was committed by another transaction since the start of the current transaction, cause the current transaction to wait.

最嚴(yán)格的隔離級別,防止其他任何事務(wù)插入或更改此事務(wù)讀取的數(shù)據(jù),直到完成為止。這樣,可以在一個(gè)事務(wù)中一遍又一遍地運(yùn)行相同的查詢,并確保每次都檢索相同的結(jié)果集。自當(dāng)前事務(wù)開始以來,任何嘗試更改另一事務(wù)提交的數(shù)據(jù)的嘗試都會(huì)導(dǎo)致當(dāng)前事務(wù)等待。

這個(gè)我就簡單演示下,因?yàn)椴粫?huì)出現(xiàn)任何問題,但是效率也最低。

最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 

如圖,執(zhí)行串行讀級別下,insert 發(fā)生阻塞,隔離級別最嚴(yán)格。

鎖機(jī)制:

1.事務(wù)在讀取數(shù)據(jù)時(shí),必須先對其加表級共享鎖(注意這里是表級) ,直到事務(wù)結(jié)束才釋放。

2.事務(wù)在更新數(shù)據(jù)時(shí),必須先對其加表級排他鎖(注意這里是表級) ,直到事務(wù)結(jié)束才釋放。

總結(jié)

到這里,我們之前的問題也有了答案。

1.不同隔離級別解決怎樣的問題:

隔離級別臟讀不可重復(fù)讀幻讀讀未提交發(fā)生發(fā)生發(fā)生讀已提交?發(fā)生發(fā)生可重復(fù)讀??可以在 next-key lock下解決
串行讀???

2.臟讀、不可重復(fù)讀、幻讀關(guān)系

最詳細(xì)MySQL事務(wù)隔離級別及原理講解!(二)

 

 

分享到:
標(biāo)簽:MySQL
用戶無頭像

網(wǎng)友整理

注冊時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定