天天看點

先了解清楚 髒讀、不可重複讀、幻讀,再談事務隔離機制

 前言

在大談事務隔離機制前,我們務必要了解   髒讀、不可重複讀、幻讀 。

因為事務隔離機制,就是為了給我們選擇權利去規避髒讀、不可重複讀、幻讀。

如果我們連問題是什麼東西都不清楚,那去了解解決各問題的方案,是不是草率了。

是以,該篇内容主要是想用些通俗易懂的話語結合執行個體去 描述下,

什麼是髒讀?

什麼是不可重複讀?

什麼是幻讀?

正文

一.什麼是髒讀?

舉個例子

我和你的操作分别代表兩個不同的事務操作(送出事務才算完成一個事務所做的事情)。

咱們公用一個錢包(共享經濟),裡面沒有錢。

你 執行一個事務操作,往錢包裡面放入 30塊錢(還未送出) 。

我 執行一個事務操作,查詢 錢包裡面有30塊錢,開心,立刻下訂單,點兩倍奶茶 。

你 神經兮兮地反悔了,放入 30塊錢的事務操作沒有送出(或者復原了)。

我 後面沒有繼續查詢錢包的錢了,一直以為裡面有30塊錢呢, 然後外賣來了, 奶茶是涼的,我也是涼的。

文字描述

事務 A 的未送出(還依然緩存)的資料被 事務 B 讀走,如果 事務 A 失敗復原,會導緻 事務 B 所讀取的的資料是錯誤的。

二.什麼是不可重複讀?

舉個例子

我和你的操作分别代表兩個不同的事務操作。

咱們公用一個錢包(共享經濟),裡面有100塊錢。

我 執行的事務 操作是,先看一眼錢包裡面的錢, 然後跟别人說我的财富是多少多少(直接吹起來了),然後吹完後還看一眼錢包裡面的錢(依依不舍)。  (同一個事務裡面包含兩次查詢,兩次查詢存在間隙)

而你執行 的操作是, 悄咪咪地動了錢包的錢。(修改操作)

場景,

我第一次看錢包裡面的錢, 是100塊, 直接開始自信吹水,我有100塊呢,奶茶随便喝。 

我吹的正起勁,你悄咪咪地 取走了錢包裡面的 90塊。

我吹水吹完了,準備再看一眼錢包的錢,結果發現,咦? 怎麼隻有10塊? 我看多了一個零嗎??? 錢包是癟的,我也是癟的。

文字描述

事務A 中 包含 兩次(多次)讀取資料值操作, 而事務B 在A的讀取操作之間 修改資料,導緻事務A 讀取的資料存在不一緻的混亂情況。

三.什麼是幻讀?

舉個例子

我和你的操作分别代表兩個不同的事務操作。

咱們公用一個錢包(共享經濟),原本有100塊錢,然後買奶茶用了30塊,剩下70塊。

大家都能看到    這條消費記錄 :       買奶茶 使用   30元 ,錢包錢數   -  30 元 。

我 執行的事務操作是, 先看一眼 錢包的消費記錄,

(心裡開始計算總額減去每一條消費記錄裡面的錢,剩下多少錢)

然後開始吹我們勤儉節約,開始計劃剩下的錢怎麼用。然後吹完後 還看一眼錢包的消費記錄(依依不舍)。 

(同一個事務裡面包含兩次查詢,兩次查詢存在間隙)

你 執行的事務操作是,悄咪咪地消費了幾次,新增了好幾條消費記錄。(新增/删除)

場景,

我第一次看錢包裡面的消費記錄,隻有一條記錄,心裡神算子附身,直接計算出 100塊減去這30塊,那還有70塊~

開始瘋狂吹水,感覺我們很節約,然後還開始計劃後續怎麼動用這筆巨款,計劃表都寫好了。

在我在那叭叭叭吹水和寫計劃表的時候, 你悄咪咪地去消費了幾把, 消費記錄 -10元; -5元 ; -15元;

等我寫完,再去留戀一把,看一下消費記錄,我人傻了。 不是隻有一條資料麼? 怎麼這麼多條???

細細一看,是不是覺得 不可重複讀  和 幻讀 ,這兩個很相似?

确實, 不可重複讀 注重的是 資料值; 而 幻讀 更注重的是 資料集的數量。

也就是說,不可重複讀其實 被影響多是 被 修改操作影響;

而 幻讀 其實 被影響多是 被 新增操作影響(删除目前大多數也隻是一個flag值了)。

Spring事務隔離機制 相比 資料庫事務隔離機制其實也就多一個 default 。

事務隔離級别 作用的簡單描述                     
ISOLATION_DEFAULT 使用後端資料庫預設的隔離級别
ISOLATION_READ_UNCOMMITTED 允許讀取尚未送出的更改。可能導緻髒讀、幻讀或不可重複讀。
ISOLATION_READ_COMMITTED (Oracle 預設級别)允許從已經送出的并發事務讀取。可防止髒讀,但幻讀和不可重複讀仍可能會發生。
ISOLATION_REPEATABLE_READ (MYSQL預設級别)對相同字段的多次讀取的結果是一緻的,除非資料被目前事務本身改變。可防止髒讀和不可重複讀,但幻讀仍可能發生。