日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

事務(wù)隔離級別

 新進(jìn)小設(shè)計 2022-02-13

隔離級別是在多個事務(wù)同時進(jìn)行更改和執(zhí)行查詢時,對性能與結(jié)果的可靠性、一致性和再現(xiàn)性之間的平衡進(jìn)行微調(diào)的設(shè)置。

提供了SQL:1992標(biāo)準(zhǔn)中描述的四種事務(wù)隔離級別:READ UNCOMMITTEDREAD COMMITTED、REPEATABLE READSERIALIZABLE。InnoDB默認(rèn)的隔離級別是REPEATABLE READ。

InnoDB使用不同的鎖定策略支持這里描述的每個事務(wù)隔離級別。下面的列表描述了MySQL如何支持不同的事務(wù)級別。

1.  REPEATABLE READ(可重復(fù)讀)

這是InnoDB的默認(rèn)隔離級別。同一個事務(wù)中的一致性讀取讀的是第一次讀取時建立的快照。這意味著,如果在同一個事務(wù)中發(fā)出幾個普通(非鎖定)SELECT語句,這些SELECT語句彼此之間也是一致的。(PS:可重復(fù)讀這個級別就是要保證同一個事務(wù)中,多次讀取相同的數(shù)據(jù),返回的結(jié)果是一樣的。)

對于鎖定讀(SELECT with FOR UPDATE or LOCK IN SHARE MODE)、UPDATE 和 DELETE 語句,鎖定取決于語句是使用具有唯一搜索條件的唯一索引,還是使用范圍類型的搜索條件。

  • 對于具有唯一搜索條件的唯一索引,InnoDB只鎖定找到的索引記錄,而不鎖定之間的間隙。
  • 對于其他搜索條件,InnoDB鎖定掃描到的索引范圍,使用間隙鎖或next-key鎖以阻止其他會話向該范圍覆蓋的間隙中插入。 

2.  READ COMMITTED(讀已提交)

即使在同一事務(wù)中,每個一致的讀取都將設(shè)置并讀取自己的新快照。(PS:對比一下,對于一致性讀,可重復(fù)讀是讀取事務(wù)中第一次讀取時候建立的快照;而讀已提交,每次都是讀最新的快照)

對于鎖讀(SELECT with For UPDATE or LOCK IN SHARE MODE)、UPDATE語句和DELETE語句,InnoDB只鎖住索引記錄,而不鎖住它們之間的間隙,從而允許在鎖住的記錄旁邊自由插入新記錄。間隙鎖定僅用于外鍵約束檢查和重復(fù)鍵檢查。 

由于禁用了間隙鎖,可能會出現(xiàn)幻像問題,因?yàn)槠渌麜捒梢栽陂g隙中插入新行。

使用READ COMMITTED具有額外的效果:

  • 對于UPDATE或DELETE語句,InnoDB僅對其更新或刪除的行持有鎖。MySQL評估WHERE條件后,將釋放不匹配行的記錄鎖。這大大降低了死鎖的可能性,但是仍然可能發(fā)生。
  • 對于UPDATE語句,如果某行已被鎖定,則InnoDB執(zhí)行“半一致”讀取,將最新的提交版本返回給MySQL,以便MySQL可以確定該行是否與UPDATE的WHERE條件匹配。如果該行匹配(必須更新),則MySQL會再次讀取該行,這一次InnoDB將其鎖定或等待對其進(jìn)行鎖定。 

舉個例子,考慮下面的語句:

CREATE TABLE t (a INT NOT NULL, b INT) ENGINE = InnoDB;
INSERT INTO t VALUES (1,2),(2,3),(3,2),(4,3),(5,2);
COMMIT;

在這種情況下,表沒有索引,因此搜索和索引掃描使用隱藏的聚集索引鎖定記錄

假設(shè),第一個會話要執(zhí)行update語句:

# Session A
START TRANSACTION;
UPDATE t SET b = 5 WHERE b = 3;

假設(shè),在第一個會話之后,第二個會話也要執(zhí)行如下update語句:

# Session B
UPDATE t SET b = 4 WHERE b = 2;

當(dāng)InnoDB執(zhí)行每個UPDATE時,它首先為讀取的每一行獲取一個排他鎖,然后決定是否修改它。如果InnoDB沒有修改該行,則釋放鎖。否則,InnoDB會保留鎖直到事務(wù)結(jié)束。這對事務(wù)處理的影響如下。

如果用默認(rèn)的REPEATABLE READ隔離級別,第一個UPDATE在其讀取的每一行上獲取一個X鎖,并且不釋放其中的任何一個:

x-lock(1,2); retain x-lock
x-lock(2,3); update(2,3) to (2,5); retain x-lock
x-lock(3,2); retain x-lock
x-lock(4,3); update(4,3) to (4,5); retain x-lock
x-lock(5,2); retain x-lock

(PS:之所以每一行都加排它鎖,是因?yàn)閎上沒有唯一索引)

第二個UPDATE在嘗試獲取任何鎖時立即阻塞(因?yàn)榈谝粋€UPDATE已在所有行上保留了鎖),并且直到第一個UPDATE提交或回滾后才繼續(xù)進(jìn)行:

x-lock(1,2); block and wait for first UPDATE to commit or roll back

如果用READ COMMITTED隔離級別,第一個UPDATE在其讀取的每一行上獲取一個X鎖,并為未修改的行釋放X鎖:

x-lock(1,2); unlock(1,2)
x-lock(2,3); update(2,3) to (2,5); retain x-lock
x-lock(3,2); unlock(3,2)
x-lock(4,3); update(4,3) to (4,5); retain x-lock
x-lock(5,2); unlock(5,2)

但是,如果WHERE條件包含一個索引列,并且InnoDB使用該索引,那么在獲取和保留記錄鎖時,只考慮索引列。

再看下面一個例子,第一個UPDATE在b = 2的每一行上獲取并保留一個X鎖。第二個UPDATE在嘗試獲取同一記錄上的X鎖時會阻塞,因?yàn)樗彩褂迷赽列上定義的索引 。

CREATE TABLE t (a INT NOT NULL, b INT, c INT, INDEX (b)) ENGINE = InnoDB;
INSERT INTO t VALUES (1,2,3),(2,2,4);
COMMIT;

# Session A
START TRANSACTION;
UPDATE t SET b = 3 WHERE b = 2 AND c = 3;

# Session B
UPDATE t SET b = 4 WHERE b = 2 AND c = 4;

(PS:b列上有索引,這兩條語句在檢索時使用了b列上的索引,因此第一會話在b=2的列上加了X鎖,第一個會話更新b=2時會阻塞)

3.  READ UNCOMMITTED(讀未提交)

會出現(xiàn)臟讀,一般不使用

4.  SERIALIZABLE(串行化)

此級別類似于REPEATABLE READ,但如果禁用了自動提交,則InnoDB會將所有普通的SELECT語句隱式轉(zhuǎn)換為SELECT ... LOCK IN SHARE MODE。 

 

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多