MySQL 事務隔離級别
基本概念
事務的基本特性
原子性(Atomicity): 當開啟事務後,後面的所有操作,要麼全部成功,要麼全部失敗。
一緻性(Consistency): 事務執行前後資料庫狀态保持一緻。
隔離性(Isolation): 在事務未送出前,它的操作對其他使用者是不可見的。
持久性(Durability): 一旦事務成功,将進行永久的變更,記錄與redo日志;
事務并發引發的問題
髒讀:所讀取的資料已經被修改了,屬于沒有意義的資料。
不可重複讀:事務A多次讀取同一條資料,事務B在A讀取的過程中對這條資料進行了更改,導緻事務A讀取的資料中出現的結果不一緻。
幻讀:同樣一個查詢錯做在整個事務過程中多次執行後,查詢所得的結果集不一樣。(側重于新增和删除操作)
事務的隔離級别
讀未送出(read-uncommitted):讀取其它事務未完成的結果。
不可重複讀(read-committed) :事務完成後,才能讀取該事務的資料更新後的結果。
可重複讀(repeatable-read) :在整個事務的過程中,對同一筆資料的讀取結果是相同的,不管其他事務是否同時在對同一筆資料進行更新,也不管其他事務對同一筆資料的更新送出與否。
串行化(serializable) :事務操作都必須依次順序執行,可以避免其他隔離級别遇到的所有問題,是最為安全的隔離級别, 但同時也是性能最差的隔離級别。
不同隔離級别引發的問題
隔離級别 髒讀 不可重複讀 幻讀
讀未送出 Yes Yes Yes
不可重複讀 No Yes Yes
可重複讀 No No Yes
串行化 No No No
案例說明
本此案例使用單表進行測試,具體表結構如下所示:
複制代碼
1 DROP TABLE IF EXISTS
user
;
2 CREATE TABLE
user
(
3
id
int(11) NOT NULL AUTO_INCREMENT,
4
name
varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
5
age
int(11) NULL DEFAULT NULL,
6
balance
int(255) NULL DEFAULT NULL,
7 PRIMARY KEY (
id
) USING BTREE
8 )
9
10 INSERT INTO
user
VALUES (1, '張三', 21, 100);
11 INSERT INTO
user
VALUES (2, '李四', 21, 0);
表中有兩條資料張三的餘額為100,李四的餘額為0;
讀未送出
在Windows環境下使用dos視窗(此處需要兩個視窗進行測試分别為A/B)進入mysql的用戶端,并切換到此表對應的資料庫下。
在A視窗和B視窗下對其事務的模式進行設定并開啟事務。
1 SET session transaction isolation level read uncommitted;
2
3 START TRANSACTION;
在視窗A中對張三的餘額進行調整(加50),在不進行送出的前提下在視窗B對張三的餘額進行查詢,結果如下:
視窗A
視窗B
我們發現用戶端B的資料也是被更新了,但是,如果有一天由于某些問題,用戶端的這次更新進行了復原操作,那麼用戶端B中查詢的資料就屬于髒資料了,這時候就會有髒讀的問題。
不可重複讀
同樣的打開兩個視窗并對其事務進行設定。
1 SET session transaction isolation level read committed;
對在視窗A中對張三的餘額進行調整(加50),在不進行送出的前提下在視窗B對張三的餘額進行查詢,結果如下:
這裡我們發現在A視窗沒有送出事務前B視窗無法拿到A視窗更新的資料,是以解決了髒讀的情況。
下來我們對A視窗的資料進行送出。并再次查詢結果。
這個時候B視窗的資料在A視窗送出事務前後的資料是不一緻的,是以會有不可重複讀的問題産生。
可重複讀
1 SET session transaction isolation level repeatable read;
對在視窗A中對張三的餘額進行調整(加50),在不進行送出的前提下在視窗B對張三的餘額進行查詢,結果如下:
此時發現已經解決了不可重複讀的問題。
這時候如果在視窗B對張三的資料再進行增加(+50)呢?那麼最終的資料會是多少呢?
可見B視窗的資料是在A視窗的基礎上進行操作的,是以資料的一緻性沒有被破壞,因為可重複讀的隔離級别下使用了MVCC機制。
下來我們在B視窗新增一條資料,并進行送出。
1 INSERT INTO
user
VALUES (3, '王五', 21, 200);
用戶端A兩次結果發生了不一緻,出現幻讀。
串行化
1 SET session transaction isolation level serializable;
視窗A對user表中的資料進行查詢,在視窗B對資料進行更新。
原文位址
https://www.cnblogs.com/brother-four/p/10711398.html