歡迎光臨
每天分享高質量文章

你真的明白什麼是幻讀嗎?

導讀:幻讀是指當事務不是獨立執行時發生的一種現象。很多程式員雖然工作多年,但是對幻讀依然瞭解的不夠。本文作者分析了幻讀出現的一般原因,並對資料庫的處理策略做了總結。


資料庫事務由4ACID定義的。隔離級別(ACID中的I)是允許使用者指定資料完整的折中方案。隔離級別越弱,產⽣問題的可能性越多。這裡我們講一下幻讀問題。

併發事務的資料更新


如果⼀個事務基於給定的資料列集合做業務決策,而沒有範圍鎖,一個併發的事務可能會導致新增一⾏記錄,引發這種特殊的情況。

在上圖中,流程如下:

  1. Alice和Bob開啟了資料庫的兩個事務;

  2. Bob讀取post_comment表中所有post_id為1的資料;

  3. Alice增加了一條post_id為1的資料;

  4. Alice提交了她的事務;

  5. 如果Bob重覆讀取post_id為1的資料,他將發現不一樣的結果集;

如果當前事務基於第一次傳回的結果做了業務決策,那麼就會產生問題。

資料庫如何防止這種現象


SQL標準這麼定義幻讀,在兩個連續的查詢之間一個併發的修改事務修改了查詢的資料集,導致這兩個查詢傳回了不同的結果。

儘管提供讀一致性是可序列化的強制要求,但是還不夠。例如,一個買家可能購買產品⽽不知道在他提交訂單之後的瞬間,商品有更低的報價。

兩階段加鎖(2PL-based)序列化隔離使用謂詞鎖,透過訪問MVCC資料庫引擎傳回的快照,來防止幻讀。

儘管如此,併發的事務仍然有可能修改被讀取過的資料。甚⾄MVCC資料庫引擎實現了事務排程,不同的請求透過兩階段加鎖實現依然可能傳回不同的結果。例如,第2個事務添加了一條記錄,不在第1個事務的讀取記錄中。在這種特殊的應⽤場景中,很多MVCC資料庫引擎將不會回滾前⾯的事務。

本文作者VLADMIHALCEA,由鄧啟明翻譯,轉載本文請註明出處,技術原創及架構實踐文章,歡迎透過公眾號選單「聯絡我們」進行投稿。

推薦閱讀


高可用架構

改變網際網路的構建方式

長按二維碼 關註「高可用架構」公眾號

贊(0)

分享創造快樂