日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

读写偏斜现象的初学者指南

發(fā)布時(shí)間:2023/12/14 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 读写偏斜现象的初学者指南 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

介紹

在關(guān)于ACID和數(shù)據(jù)庫事務(wù)的文章中,我介紹了SQL標(biāo)準(zhǔn)描述的三種現(xiàn)象:

  • 臟讀
  • 不可重復(fù)讀
  • 幻讀

盡管這些可以很好地區(qū)分四個(gè)隔離級(jí)別(未提交讀,已提交讀,可重復(fù)讀和可序列化),但實(shí)際上,還有更多的現(xiàn)象需要考慮。 1995年的論文(《 ANSI SQL隔離級(jí)別批判》)介紹了標(biāo)準(zhǔn)規(guī)范中省略的其他現(xiàn)象。

在我的《高性能Java持久性》一書中,我決定堅(jiān)持“事務(wù)”一章,因?yàn)樗鼘?shù)據(jù)訪問的有效性和效率都非常重要。

領(lǐng)域模型

對于以下示例,我將使用以下兩個(gè)實(shí)體:

在我們的虛構(gòu)應(yīng)用程序中,更改“ 帖子”標(biāo)題后,必須將作者記錄在關(guān)聯(lián)的“ PostDetails”記錄中。 如果未防止讀寫時(shí)滯,則可以破壞此域模型約束,如以下測試案例所示。

讀取歪斜

以下測試模擬了讀取偏斜如何發(fā)生:

doInConnection(aliceConnection -> {prepareConnection(aliceConnection);String title = selectStringColumn(aliceConnection, selectPostTitleSql());executeSync(() -> {doInConnection(bobConnection -> {prepareConnection(bobConnection);try {update(bobConnection, updatePostTitleParamSql(), new Object[]{"Bob"});update(bobConnection, updatePostDetailsAuthorParamSql(), new Object[]{"Bob"});} catch (Exception e) {LOGGER.info("Exception thrown", e);preventedByLocking.set(true);}});});String createdBy = selectStringColumn(aliceConnection, selectPostDetailsAuthorSql()); });
  • 愛麗絲選擇一個(gè)帖子標(biāo)題
  • Bob潛入并更新了Post和PostDetails實(shí)體
  • Alice線程將繼續(xù),并且她選擇PostDetails記錄

如果允許讀取偏斜,則Alice會(huì)看到Bob的更新,并且可以假定先前的Post版本(在交易開始時(shí)讀取)是Bob發(fā)行的(可能不準(zhǔn)確)。

在四個(gè)最常見的關(guān)系數(shù)據(jù)庫系統(tǒng)上運(yùn)行此測試可獲得以下結(jié)果:

數(shù)據(jù)庫隔離級(jí)別 讀取歪斜
Oracle讀已提交
Oracle可序列化 沒有
SQL Server讀未提交
SQL Server讀取已提交
SQL Server讀取提交的快照隔離
SQL Server可重復(fù)讀取 沒有
SQL Server可序列化 沒有
SQL Server快照隔離 沒有
PostgreSQL讀未提交
PostgreSQL讀已提交
PostgreSQL可重復(fù)讀 沒有
PostgreSQL可序列化 沒有
MySQL讀取未提交
MySQL讀取提交
MySQL可重復(fù)讀 沒有
MySQL可序列化 沒有

寫偏斜

要模擬寫偏斜,您需要執(zhí)行以下測試用例:

doInConnection(aliceConnection -> {prepareConnection(aliceConnection);String title = selectStringColumn(aliceConnection, selectPostTitleSql());String createdBy = selectStringColumn(aliceConnection, selectPostDetailsAuthorSql());executeSync(() -> {doInConnection(bobConnection -> {prepareConnection(bobConnection);try {String bobTitle = selectStringColumn(bobConnection, selectPostTitleSql());String bonCreatedBy = selectStringColumn(bobConnection, selectPostDetailsAuthorSql());update(bobConnection, updatePostTitleParamSql(), new Object[]{"Bob"});} catch (Exception e) {LOGGER.info("Exception thrown", e);preventedByLocking.set(true);}});});update(aliceConnection, updatePostDetailsAuthorParamSql(), new Object[]{"Alice"}); });
  • 愛麗絲從PostDetails記錄中選擇Post標(biāo)題和作者
  • Bob還選擇了Post標(biāo)題和相關(guān)的作者,但他決定僅更新標(biāo)題
  • 愛麗絲想在不更改帖子標(biāo)題的情況下更新PostDetails記錄

如果允許寫偏斜,則將執(zhí)行Alice和Bob不相交的寫操作,而不會(huì)受到控制這兩個(gè)記錄的約束的阻止。

在四個(gè)最常見的關(guān)系數(shù)據(jù)庫系統(tǒng)上運(yùn)行此測試可獲得以下結(jié)果:

數(shù)據(jù)庫隔離級(jí)別 寫偏斜
Oracle讀已提交
Oracle可序列化
SQL Server讀未提交
SQL Server讀取已提交
SQL Server讀取提交的快照隔離
SQL Server可重復(fù)讀取 沒有
SQL Server可序列化 沒有
SQL Server快照隔離
PostgreSQL讀未提交
PostgreSQL讀已提交
PostgreSQL可重復(fù)讀
PostgreSQL可序列化 沒有
MySQL讀取未提交
MySQL讀取提交
MySQL可重復(fù)讀
MySQL可序列化 沒有

  • 寫偏斜在多版本并發(fā)控制機(jī)制中很普遍,即使聲稱使用“可序列化”,Oracle也無法阻止它,而實(shí)際上它只是一個(gè)快照隔離級(jí)別。
  • 當(dāng)使用“可重復(fù)讀”和“可序列化”時(shí),SQL Server默認(rèn)的基于鎖定的隔離級(jí)別可以防止寫偏斜。 快照隔離級(jí)別(基于MVCC)中的任何一個(gè)都不能阻止/檢測到它。
  • PostgreSQL使用更高級(jí)的可序列化快照隔離級(jí)別來阻止它
  • MySQL在使用Serializable時(shí)會(huì)使用共享鎖,因此即使InnoDB也是基于MVCC的,也可以防止寫偏斜

如果您對此主題感興趣,那么您也可以閱讀我正在編寫的《 高性能Java持久性》一書。

翻譯自: https://www.javacodegeeks.com/2015/10/a-beginners-guide-to-read-and-write-skew-phenomena.html

總結(jié)

以上是生活随笔為你收集整理的读写偏斜现象的初学者指南的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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