Mysql事務隔離機制

2021-09-24 19:24:24 字數 3732 閱讀 4291

了解mysql事務隔離機制首先需要理解什麼是acid:

a : 原子性automicity,乙個事務作為不可分割的最小單元,乙個事務裡面的所有操作要麼全部成功,要麼全部失敗。

c:一致性consistency,事物結束後系統狀態是一致的,即 資料不能平白無故的產生,也不能平白無故的消失,例如乙個轉賬業務事務,最終所有賬戶餘額不變。

i:隔離性isolation,簡單的講,乙個事務所有的操作,在最後commit 之前,所有修改對其他事務不可見

d:永續性durability,當事務提交後,資料應該永久被儲存到資料中,即使發生了災難性後果,資料也不會丟失

在實際的運用情況下實現acid是非常困難的,而且效能上也會大打折扣,很多時候不同的業務對事務的要求不一樣,所以為了提公升效能並滿足業務,資料庫提供了4種不同的隔離級別來供使用者選擇

未提交讀(read uncommitted): 這種級別,當乙個事務對資料進行修改後,即使沒有提交,也會被其他事務讀取到,高併發狀態下極易產生髒讀。

已提交讀(read committed):在乙個事務的整個操作過程中,所有的資料修改對其他事務不可見,但這種情況下會導致其他事務中產生不可重複讀(即兩次讀取結果不一致),這個級別也叫作不可重複讀

可重複讀(repeatable read):mysql的預設事務隔離級別,該級別可以保證乙個事務在整個流程中,多次讀取同樣記錄的結果相同,但是沒有解決幻讀的問題。

可序列化(serializable): 是事務最高隔離級別,對同一張表的所有的讀寫都會阻塞,每次都需要獲取表級共享鎖

資料庫的事務隔離越嚴格,併發***越小,但付出的代價也就越大,因為事務隔離實質上就是使事務在一定程度上「序列化」進行,這顯然與「併發」是矛盾的。

同時,不同的應用對讀一致性和事務隔離程度的要求也是不同的,比如許多應用對「不可重複讀"和「幻讀」並不敏感,可能更關心資料併發訪問的能力。

更新丟失:當兩個或多個事務選擇同一行,然後基於最初選定的值更新該行時,由於每個事務都不知道其他事務的存在,就會發生丟失更新問題–最後的更新覆蓋了由其他事務所做的更新。與後面的事務隔離級別無關,因為update、delete 都是更新最新的資料,一般使用樂觀鎖或者悲觀鎖來解決。

髒讀: 事務a讀取到另乙個事務b未提交的修改,事務b回滾修改,那麼事務a就讀取了髒讀。

不可重複讀: 事務a讀取記錄c,在這個過程中事務b將記錄c修改中欄位進行修改,那麼當事務a再次讀取記錄c時,獲取到的結果與第一次不同,叫做不可重複讀。【mvcc版本控制器開解決】

幻讀:幻讀於不可重複讀類似,當事務a第一次讀取某個範圍記錄後,事務b新增了一條記錄,事務a在此讀取這個範圍是會多一條記錄導致幻讀出現【間隙鎖解決幻讀的問題】

隔離級別

髒讀不可重複讀

幻讀未提交讀(read uncommitted)

存在存在

存在已提交讀(read committed)

不存在存在

存在可重複讀(repeatable read)

不存在不存在

存在可序列化(serializable)

不存在不存在

不存在有興趣的同學可以開啟幾個sql命令介面,試一下上面的場景,以下是一些常用的事務處理sql:

select @@tx_isolation;  -- 查詢當前隔離機制

begin; -- 開始事務

rollback; -- 回滾

commit; -- 提交

-- 設定當前會話隔離級別

set session transaction isolation level read uncommitted; -- 未提交讀

set session transaction isolation level read committed; -- 已提交讀

set session transaction isolation level repeatable read; -- 可重複讀

set session transaction isolation level serializable; -- 可序列化

-- 設定系統隔離級別

set global transaction isolation level read uncommitted; -- 未提交讀

set global transaction isolation level read committed; -- 已提交讀

set global transaction isolation level repeatable read; -- 可重複讀

set global transaction isolation level serializable; -- 可序列化

spring 事務傳播機制以及隔離級別:

@transactional(rollbackfor = exception.class,isolation = isolation.read_committed)

引數值名稱

解釋isolation. default

default

預設的事務隔離級別,預設是用資料庫的事務隔離級別

isolation. read_uncommitted

未提交讀

髒讀,不可重複讀、幻讀都存在

isolation. read_committed

已提交讀

避免髒讀,但是存在不可重複讀,幻讀

isolation. repeatable_read

可重複讀

避免髒讀和不可重複讀,但是有幻讀的可能

isolation. serializable

序列話避免以上所有讀的問題

例項演示:

新建 user 表,用於演示:

create table `user` (

`id` int not null auto_increment,

`name` varchar(24) default null comment '姓名',

`age` int default null comment '年齡',

primary key (`id`)

) engine=innodb auto_increment=1 default charset=utf8 comment='使用者資訊表';

未提交讀 狀態下的髒讀演示:

- 第一步:開啟事務a、b,並設定鼓勵狀態為 未提交讀。

- 第二步:事務b查詢表結果為空。

- 第三步:事務b插入一條資料,不提交

- 第四步:事務a進行表資料查詢,則查詢到了事務b新增未提交的資料。

- 第五步:事務b回滾提交,造成事務a產生了髒讀。

已提交讀 出現的 不可重複讀 現象:

可重複讀 存在的幻讀可能【幻讀演示,會存在mvcc的影響】:

解釋: 可重複讀的隔離級別下會使用了mvcc機制,當我們執行select操作不會更新版本號,是快照讀(歷史版本);insert、update和delete會更新版本號, 會出現幻讀的情況。為解決 幻讀 的情況 mysql 引入了 間隙鎖,這裡先不做解釋。

注意: 關於 mvcc 和 mysql鎖【間隙鎖】 博主後面的博文會進行解釋。

mysql對映機制 mysql事務隔離機制及其原理

目錄 事務特性acid屬性 併發事務帶來的問題 事務隔離級別 事務實現原理 閒聊 邁莫coding 事務特性acid屬性 事務特性指的就是acid,如圖所示 在這裡插入描述 原子性 atomicity 乙個事務 transaction 中的所有操作,或者全部完成,或者全部不完成,不會結束在中間某個環...

事務隔離機制

五年前在論壇上有過一次提問,如下 下面兩個問題的答案就是資料庫的事務隔離機制。資料庫針對外部的併發請求,也是要考慮資源搶占問題的,所以資料庫針對同一記錄的寫請求,也是要加鎖的!最簡單的方式就是針對每個請求都加鎖,全部序列,這樣肯定不會有問題。但這樣效能很低,所以db將鎖分為了讀鎖和寫鎖,也就是常說的...

Mysql 中的事務隔離機制

0.read uncommitted 可以讀未提交事務資料 髒讀 1.read committed 只可以讀提交事務資料 不可重複讀 2.repeatable read 只有兩個事務都提交,才可以讀到新資料 幻讀 3.serializable 只有乙個事務可以運算元據,無論讀寫,其他事務等待 set...