天天看點

Sql Server Snapshot和mysql MVCC

mysql

在一個事務A中插入一條資料

在B事務中查詢到的還是以前的資料,可以select *from table,不被鎖住

Sql Server 預設級别 讀已送出

是以A事務在 X表插入資料,在未送出的情況下,則B事務無法做 包含A事務新資料的 操作。

具體地說 B事務無法做全量的資料查詢,

B事務也無法單條查詢新資料行

B事務可以查詢其他資料行

B事務依然可以插入新資料

B事務不能查詢count

如果最新的資料是B事務插入的 B事務可以查詢maxId,如過最新資料為A插入 那麼A事務可以查詢maxid 而不用等待鎖。

B事務加With (nolock) 可以查詢A事務中的新增行 也可以查詢count。這是髒讀

A事務在 X表更新資料行,則B事務也無法做 關于A事務所操作的資料行 的查詢,可操作其他行

B事務也不能更新剛剛A事務操作的資料行、

B事務可以查詢max

由于預設級别是讀已送出,是以存在不可重複讀的問題。兩次查詢的單行和多行資料可能會不同。

下面建立新資料庫 并開啟MVCC的情況:

ALTER DATABASE testdb3 SET allow_snapshot_isolation ON
ALTER DATABASE testdb3 SET READ_COMMITTED_SNAPSHOT ON      

開啟SNAPSHOT後,上述需要加with nolock才能查詢的資料,不再需要nolock了,并且MVCC機制保障了我們不會有髒讀。

但是目前并非可重複讀級别,幻讀依然存在。必須要說,我覺得與其稱為幻讀,不如叫做幻行。

下面說說SqlServer可重複讀級别,當一個資料庫連接配接A 的事務隔離設定為此級别。

如果A已經查詢過資料行X,那麼B事務對X的修改要等A事務結束。這就保證了在一次事務A中,多次查詢同一條資料結果是相同的。

注意SqlServer在此隔離級别下,即使加上快照,也無法避免幻讀. 此快照就算MVCC機制

但是mysql innodb 隔離級别預設為可重複讀,并且其MVCC機制,可以避免幻讀。

總之mvcc降低了鎖開銷,提高了并發能力。非鎖定讀。