8 MySQL 事務到底是隔離還是不隔離呢

2021-10-23 00:06:52 字數 2849 閱讀 2850

begin/start transaction 命令並不是乙個事務的起點,在執行到它們之後的第乙個操作 innodb 表的語句,事務才真正啟動。

馬上啟動乙個事務,可以使用 start transaction with consistent snapshot 這個命令

view,使用查詢語句定義的虛擬表。語法: create view …

innodb在實現mvcc時用到的一致性讀檢視,consistent read view,用於支援rc(read committed)和rr(repeatable read)隔離級別實現。

在可重複讀隔離級別下,事務在啟動的時候就「拍了個快照」。注意,這個快照是基於整庫的。

圖中的三個虛線箭頭,就是undo log

如果落在綠色部分,表示這個版本是已提交的事務或者是當前事務自己生成的,這個資料是可見的;

如果落在紅色部分,表示這個版本是由將來啟動的事務生成的,是肯定不可見的;

如果落在黃色部分,那就包括兩種情況

a. 若 row trx_id 在陣列中,表示這個版本是由還沒提交的事務生成的,不可見;

b. 若 row trx_id 不在陣列中,表示這個版本是已經提交了的事務生成的,可見。

比如,對於圖行狀態變更圖中的資料來說,如果有乙個事務,它的低水位是 18,那麼當它訪問這一行資料時,就會從 v4 通過 u3 計算出 v3,所以在它看來,這一行的值是 11。

innodb 利用了「所有資料都有多個版本」的這個特性,實現了「秒級建立快照」的能力

例子:

mysql> create table `t` (

如圖:事務a、b、c

事務a,返回的結果 k = 1,為什麼?

假設:事務 a 開始前,系統裡面只有乙個活躍事務 id 是 99;

事務 a、b、c 的版本號分別是 100、101、102,且當前系統裡只有這四個事務;

三個事務開始前,(1,1)這一行資料的 row trx_id 是 90。

這樣,事務 a 的檢視陣列就是[99,100], 事務 b 的檢視陣列是[99,100,101], 事務 c 的檢視陣列是[99,100,101,102]。

如圖 事務 a 查詢資料邏輯圖

可見。這樣執行下來,雖然期間這一行資料被修改過,但是事務 a 不論在什麼時候查詢,看到這行資料的結果都是一致的,所以我們稱之為一致性讀

事務 b 的 update 語句,查詢結果k=3?

如圖 事務 b 更新邏輯圖

更新資料都是先讀後寫的,而這個讀,只能讀當前的值,稱為「當前讀」(current read)。

//讀鎖(s 鎖,共享鎖)

mysql> select k from t where id=1 lock in share mode;

//寫鎖(x 鎖,排他鎖)

mysql> select k from t where id=1 for update;

假設事務 c 不是馬上提交的,而是變成了下面的事務 c』,會怎麼樣呢?

如圖 事務 a、b、c』的執行流程

事務的可重複讀的能力是怎麼實現的?

可重複讀的核心就是一致性讀(consistent read);而事務更新資料的時候,只能用當前讀。如果當前的記錄的行鎖被其他事務占用的話,就需要進入鎖等待。

事務隔離級別是可重複讀。現在,我要把所有「字段 c 和 id 值相等的行」的 c 值清零,但是卻發現了乙個「詭異」的、改不掉的情況。請你構造出這種情況,並說明其原理。

mysql> create table `t` (

`id` int(11) not null,

`c` int(11) default null,

primary key (`id`)

) engine=innodb;

insert into t(id, c) values(1,1),(2,2),(3,3),(4,4);

復現出來以後,再思考一下,在實際的業務開發中有沒有可能碰到這種情況?你的應用**會不會掉進這個「坑」裡,你又是怎麼解決的呢?

文中有個概念:更新資料都是先讀後寫的,而這個讀,只能讀當前的值,稱為「當前讀」(current read)。

本題中只需在 update t set c=0 where c = id 之前另乙個事務將 c+ 1。按下面操作兩個事務,可以重現

事務到底是隔離的還是不隔離的?

在之前很長一段時間內,對事務的隔離機制都僅僅侷限在 背 這個字上,但是對於底層如何實現解決的可重複讀和幻讀等一系列問題還是雲裡霧裡。這篇文章,主要還是講述的是在不可重複讀隔離級別下,多事務之間實現的一致性讀和當前讀以及多事務版本併發控制的細節原理,以便於加深對mysql隔離機制的理解,當然後面還會引...

08 事務到底是隔離的還是不隔離的?

在第 3 篇文章講事務隔離級別的時候提到過,如果是可重複讀隔離級別,事務 t 啟動的時候會建立乙個檢視 read view,之後事務 t 執行期間,即使有其他事務修改了資料,事務 t 看到的仍然跟在啟動時看到的一樣。也就是說,乙個在可重複讀隔離級別下執行的事務,好像與世無爭,不受外界影響。我給你舉乙...

到底是main還是WinMain

在 裡看到一句 void winapi setlog int itracelevel 一直不明白,知道看到下面的部落格 在vs2008中新建了乙個win32的空工程,準備從0開始,每一行 都自己寫。1 libcmt.lib wincrt0.obj error lnk2019 unresolved e...