21、MySQL事務(wù)

一、(了解)定義

全稱(Transaction Control Language)翻譯成中文 事務(wù)控制語(yǔ)言,事務(wù)是訪問(wèn)并可能更新數(shù)據(jù)庫(kù)各種數(shù)據(jù)項(xiàng)的一個(gè)程序執(zhí)行單元,

是并發(fā)控制的單元,是用戶定義的一個(gè)操作序列。這些操作要么都做,要么都不做,是一個(gè)不可分割的工作單位。通過(guò)事務(wù),sql 能將邏輯相關(guān)的一組操作綁定在一起,以便服務(wù)器 保持?jǐn)?shù)據(jù)的完整性。

二、 (了解)為什么要事務(wù)

設(shè)想網(wǎng)上購(gòu)物的一次交易,其付款過(guò)程至少包括以下幾步數(shù)據(jù)庫(kù)操作:

  1. 更新客戶所購(gòu)商品的庫(kù)存信息
  2. 保存客戶付款信息--可能包括與銀行系統(tǒng)的交互
  3. 生成訂單并且保存到數(shù)據(jù)庫(kù)中
  4. 更新用戶相關(guān)信息,例如購(gòu)物數(shù)量等等

正常的情況下,這些操作將順利進(jìn)行,最終交易成功,與交易相關(guān)的所有數(shù)據(jù)庫(kù)信息也成功地更新。但是,如果在這一系列過(guò)程中任何一個(gè)環(huán)節(jié)出了差錯(cuò),例如在更新商品庫(kù)存信息時(shí)發(fā)生異常、該顧客銀行帳戶存款不足等,都將導(dǎo)致交易失敗。一旦交易失敗,數(shù)據(jù)庫(kù)中所有信息都必須保持交易前的狀態(tài)不變,比如最后一步更新用戶信息時(shí)失敗而導(dǎo)致交易失敗,那么必須保證這筆失敗的交易不影響數(shù)據(jù)庫(kù)的狀態(tài)--庫(kù)存信息沒(méi)有被更新、用戶也沒(méi)有付款,訂單也沒(méi)有生成。否則,數(shù)據(jù)庫(kù)的信息將會(huì)一片混亂而不可預(yù)測(cè)。

  1. 數(shù)據(jù)庫(kù)事務(wù)正是用來(lái)保證這種情況下交易的平穩(wěn)性和可預(yù)測(cè)性的技術(shù)

  2. 默認(rèn)情況下會(huì)自動(dòng)提交,也就是說(shuō)每個(gè)SQL語(yǔ)句都是在其完成時(shí)提交到數(shù)據(jù)庫(kù)。

  3. 事務(wù)只針對(duì)DDL操作

三、(熟練掌握)事務(wù)的特性(ACID)

1、案例

A賬戶向B賬號(hào)匯錢的例子來(lái)說(shuō)明如何通過(guò)數(shù)據(jù)庫(kù)事務(wù)保證數(shù)據(jù)的準(zhǔn)確性和完整性

1、從A賬號(hào)中把余額讀出來(lái)(500)

2、對(duì)A賬號(hào)做減法操作(500-100)

3、把結(jié)果寫回A賬號(hào)中(400)

4、從B賬號(hào)中把余額讀出來(lái)(500

5、對(duì)B賬號(hào)做加法操作(500+100)

6、把結(jié)果寫回B賬號(hào)中(600)

2、原子性(Atomicity)

  1. 概念
    事務(wù)是數(shù)據(jù)庫(kù)的邏輯工作單位,而且是必須是原子工作單位,對(duì)于其數(shù)據(jù)修改,要么全部執(zhí)行,要么全部不執(zhí)行。
  2. 說(shuō)明
    保證1-6所有過(guò)程要么都執(zhí)行,要么都不執(zhí)行。一旦在執(zhí)行某一步驟的過(guò)程中發(fā)生問(wèn)題,就需要執(zhí)行回滾操作。 假如執(zhí)行到第五步的時(shí)候,B賬戶突然不可用(比如被注銷),那么之前的所有操作都應(yīng)該回滾到執(zhí)行事務(wù)之前的狀態(tài)

3、一致性(Consistency)

  1. 概念
    指在事務(wù)開(kāi)始之前和事務(wù)結(jié)束以后,數(shù)據(jù)庫(kù)的完整性約束沒(méi)有被破壞。也就是說(shuō)數(shù)據(jù)庫(kù)事務(wù)不能破壞關(guān)系數(shù)據(jù)的完整性以及業(yè)務(wù)邏輯上的一致性。
    注: **
    業(yè)務(wù)邏輯上的一致性 由開(kāi)發(fā)人員進(jìn)行保證。
    數(shù)據(jù)庫(kù)層面 在一個(gè)事務(wù)執(zhí)行之前和之后,數(shù)據(jù)會(huì)符合你設(shè)置的
    約束唯一約束,外鍵約束,check約束**等)和觸發(fā)器設(shè)置,并且同一個(gè)事務(wù)內(nèi)部的一組操作必須全部執(zhí)行成功(原子操作)
    但是,原子性并不能完全保證一致性。在多個(gè)事務(wù)并行進(jìn)行的情況下,即使保證了每一個(gè)事務(wù)的原子性,仍然可能導(dǎo)致數(shù)據(jù)不一致的結(jié)果。為了保證并發(fā)情況下的一致性,引入了隔離性
  2. 說(shuō)明
    在轉(zhuǎn)賬之前,A和B的賬戶中共有500+500=1000元錢。在轉(zhuǎn)賬之后,A和B的賬戶中共有400+600=1000元。也就是說(shuō),數(shù)據(jù)的狀態(tài)在執(zhí)行該事務(wù)操作之后從一個(gè)狀態(tài)改變到了另外一個(gè)狀態(tài)。同時(shí)一致性還能保證賬戶余額不會(huì)變成負(fù)數(shù)等

4、隔離性(Isolation)

  1. 概念
    也稱為獨(dú)立性,是指并行事務(wù)的修改必須與其他并行事務(wù)的修改相互獨(dú)立。一個(gè)事務(wù)處理數(shù)據(jù),要么是其他事務(wù)執(zhí)行之前的狀態(tài),要么是其他事務(wù)執(zhí)行之后的狀態(tài),但不能處理其他正在處理的數(shù)據(jù)。
    企業(yè)級(jí)的數(shù)據(jù)庫(kù)每一秒鐘都可能應(yīng)付成千上萬(wàn)的并發(fā)訪問(wèn),因而帶來(lái)了并發(fā)控制的問(wèn)題。
  2. 說(shuō)明
    在A向B轉(zhuǎn)賬的整個(gè)過(guò)程中,只要事務(wù)還沒(méi)有提交(commit),查詢A賬戶和B賬戶的時(shí)候,兩個(gè)賬戶里面的錢的數(shù)量都不會(huì)有變化。
    如果在A給B轉(zhuǎn)賬的同時(shí),有另外一個(gè)事務(wù)執(zhí)行了C給B轉(zhuǎn)賬的操作,那么當(dāng)兩個(gè)事務(wù)都結(jié)束的時(shí)候,B賬戶里面的錢應(yīng)該是A轉(zhuǎn)給B的錢加上C轉(zhuǎn)給B的錢再加上自己原有的錢

5、持久性(Durability)

  1. 概念
    一個(gè)事務(wù)一旦提交,事物的操作便永久性的保存在DB中。即使此時(shí)再執(zhí)行回滾操作也不能撤消所做的更改
  2. 說(shuō)明
    一旦轉(zhuǎn)賬成功(事務(wù)提交),兩個(gè)賬戶的里面的錢就會(huì)真的發(fā)生變化(會(huì)把數(shù)據(jù)寫入數(shù)據(jù)庫(kù)做持久化保存)

四、(熟練掌握)基本操作

1、事務(wù)常用的語(yǔ)句

語(yǔ)句
BEGIN或START TRANSACTION 顯式地開(kāi)啟一個(gè)事務(wù);
COMMIT 也可以使用COMMIT WORK,不過(guò)二者是等價(jià)的。COMMIT會(huì)提交事務(wù),并使已對(duì)數(shù)據(jù)庫(kù)進(jìn)行的所有修改成為永久性的;
ROLLBACK 有可以使用ROLLBACK WORK,回滾會(huì)結(jié)束用戶的事務(wù),并撤銷正在進(jìn)行的所有未提交的修改;
SAVEPOINT identifier SAVEPOINT允許在事務(wù)中創(chuàng)建一個(gè)保存點(diǎn),一個(gè)事務(wù)中可以有多個(gè)SAVEPOINT;
RELEASE SAVEPOINT identifier 刪除一個(gè)事務(wù)的保存點(diǎn),當(dāng)沒(méi)有指定的保存點(diǎn)時(shí),執(zhí)行該語(yǔ)句會(huì)拋出一個(gè)異常;
ROLLBACK TO identifier; 把事務(wù)回滾到標(biāo)記點(diǎn);
SET TRANSACTION 用來(lái)設(shè)置事務(wù)的隔離級(jí)別。InnoDB存儲(chǔ)引擎提供事務(wù)的隔離級(jí)別有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ和SERIALIZABLE。

2、MYSQL 事務(wù)處理主要有兩種方法:

  1. 用 BEGIN, ROLLBACK, COMMIT來(lái)實(shí)現(xiàn)
    • BEGIN 開(kāi)始一個(gè)事務(wù)
    • ROLLBACK 事務(wù)回滾
    • COMMIT事務(wù)提交
  2. 直接用 SET 來(lái)改變 MySQL 的自動(dòng)提交模式
    • SET AUTOCOMMIT=0 | off 禁止自動(dòng)提交
    • **SET AUTOCOMMIT=1 | on ** 開(kāi)啟自動(dòng)提交

3 、案例

  1. 前期準(zhǔn)備工作
    -- 創(chuàng)建銀行賬戶表
    create table account(
        aid int primary key auto_increment comment '主鍵',
        card_no varchar(16) not null unique comment '銀行卡號(hào)',
        name varchar(20) not null comment '姓名',
        money decimal(10,2) default 0.0 comment '金額'
    )
    -- 插入數(shù)據(jù)
    insert into account (card_no,name,money) values
    ('1', '小明', 1000),
    ('2', '嬌嬌', 1000);
    
  2. 第一步 開(kāi)始事務(wù)
    -- 告訴系統(tǒng)以下所有操作,不要直接寫入數(shù)據(jù)庫(kù),先存到事務(wù)日志。
    BEGIN
    
  3. 第二步 減少賬戶的余額
    update account set money = money - 1000 where cardno =1
    
  4. 第三步 增加賬戶的余額
    update account set money = money + 1000 where cardno = 2;
    
  5. 第四步 提交事務(wù)
    commit;
    
  6. 第五步 或者回滾
    rollback
    

五、(掌握)事務(wù)隔離 - 并發(fā)控制

數(shù)據(jù)庫(kù)事務(wù)處理相關(guān)命令

操作命令 說(shuō)明
SHOW CREATE TABLE 表名; 查看存儲(chǔ)引擎
SET AUTOCOMMIT=0或1;或者 SET AUTOCOMMIT=off 或 on 設(shè)置是否自動(dòng)提交
SELECT @@AUTOCOMMIT; 或者 show variables like '%commit%'; 查詢自動(dòng)提交功能狀態(tài)
SELECT @@tx_isolation; 查看事務(wù)隔離級(jí)別
SET tx_isolation='READ-UNCOMMITTED'; 設(shè)置事務(wù)的隔離級(jí)別

1、并發(fā)控制

數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)中的并發(fā)控制的任務(wù)是確保在多個(gè)事務(wù)同時(shí)存取數(shù)據(jù)庫(kù)中同一數(shù)據(jù)時(shí)不破壞事務(wù)的隔離性和統(tǒng)一性以及數(shù)據(jù)庫(kù)的統(tǒng)一性

2、不考慮事務(wù)的隔離性,會(huì)出現(xiàn)什么問(wèn)題?

  1. 臟讀:一個(gè)事務(wù)讀取到另一個(gè)事務(wù)的未提交數(shù)據(jù)
  2. 不可重復(fù)讀:兩次讀取的數(shù)據(jù)不一致(強(qiáng)調(diào)update 針對(duì)單行)
  3. 虛讀(幻讀):兩次讀取的數(shù)據(jù)不一致(強(qiáng)調(diào)insert或delete,范圍查詢)
  4. 丟失更新:撤銷一個(gè)事務(wù)時(shí),把其他事務(wù)已提交的更新數(shù)據(jù)覆蓋(事務(wù)A和B并發(fā)執(zhí)行,A事務(wù)執(zhí)行更新后,提交;B事務(wù)在A事務(wù)更新后,B事務(wù)結(jié)束前也做了對(duì)該行數(shù)據(jù)的更新操作,然后回滾,則兩次更新操作都丟失了)

3、四種隔離級(jí)別

  1. Read-uncommitted:最低級(jí)別,以上情況均無(wú)法保證。(讀未提交)
  2. Read-committed:可避免臟讀情況發(fā)生(讀已提交)
  3. Repeatable-read:可避免臟讀、不可重復(fù)讀情況的發(fā)生。(可重復(fù)讀)不可以避免虛讀
  4. Serializable:可避免臟讀、不可重復(fù)讀、虛讀情況的發(fā)生。(串行,不僅有read、write鎖還有range lock范圍鎖(沒(méi)有where鎖全表,有where鎖where范圍);對(duì)一張表的所有增刪改操作必須順序執(zhí)行,性能最差)
    | 隔離級(jí)別 | 臟讀 | 不可重復(fù)讀 | 幻讀 |
    | ---------------- | ---- | ---------- | ---- |
    | Read uncommitted | √ | √ | √ |
    | Read committed | × | √ | √ |
    | Repeatable read | × | × | √ |
    | Serializable | × | × | × |

六、(掌握)隔離級(jí)別詳解

1、Read uncommitted

  1. 作用
    所有事務(wù)都可以看到其他未提交事務(wù)的執(zhí)行結(jié)果
  2. 舉個(gè)栗子
    又到月底了,小明的老婆要準(zhǔn)備給小明發(fā)生活費(fèi)了,小明的老婆給小明打了500塊,但該事務(wù)并沒(méi)有提交,而此時(shí)小明正好在查余額,發(fā)現(xiàn)是550塊,高興的差點(diǎn)蹦了起來(lái).天有不測(cè)風(fēng)云,突然小明的老婆發(fā)現(xiàn)多打了50塊,于是回滾事務(wù),修改金額,然后將事務(wù)提交,最后小明空歡喜異常。
  3. 示例圖


    image
  4. 示例代碼
    -- ****打開(kāi)兩個(gè)窗口 事務(wù)A窗口****
    -- 1.查看事務(wù)隔離級(jí)別
    SELECT @@TX_ISOLATION;
    +------------------+
    | @@tx_isolation   |
    +------------------+
    | READ-UNCOMMITTED |
    +------------------+
    -- 2.設(shè)置事務(wù)的隔離級(jí)別為讀取未提交
    SET tx_isolation='READ-UNCOMMITTED';
    -- 3.查看自動(dòng)提交狀態(tài)
    SELECT @@AUTOCOMMIT;
    -- 4.如果自動(dòng)提交開(kāi)啟,關(guān)閉自動(dòng)提交
    SET AUTOCOMMIT = 0;
    --  ****在事務(wù)A中執(zhí)行更新語(yǔ)句,且不提交****
    -- 5. 開(kāi)啟事務(wù)
    START TRANSACTION;
    -- 6.  將賬戶小明的賬號(hào)的錢減100
    UPDATE account SET  money = money - 100 WHERE aid = 1;
    --  不要提交  切換到事務(wù)B的窗口
    -- 7. 事務(wù)回滾
    ROLLBACK
    
    -- 事務(wù)B窗口
    -- 1. 查看事務(wù)的隔離級(jí)別
    SELECT @@TX_ISOLATION;
    -- 2.設(shè)置事務(wù)的隔離級(jí)別
    SET TX_ISOLATION = 'READ-UNCOMMITTED';
    -- 3.查詢小明的賬號(hào)
    SELECT * from  account WHERE aid = 1
    -- ****顯示的信息****
    +-----+---------+--------+--------+
    | aid | card_no | name   | money  |
    +-----+---------+--------+--------+
    |   1 | 1       | 小明   | 700.00 |
    +-----+---------+--------+--------+
    --  4. 將事務(wù)隔離級(jí)別設(shè)置成讀取已提交或者其他
    SET TX_ISOLATION = 'READ-COMMITTED';
    -- 5. 在次查詢發(fā)現(xiàn)賬號(hào)余額是800
    SELECT * from  account WHERE aid = 1;
    -- ****顯示的信息****
    +-----+---------+--------+--------+
    | aid | card_no | name   | money  |
    +-----+---------+--------+--------+
    |   1 | 1       | 小明   | 800.00 |
    +-----+---------+--------+--------+
    -- 切回事務(wù)B 使用回滾 rollback
    

2、Read committed

  1. 作用
    一個(gè)事務(wù)只能看見(jiàn)已經(jīng)提交事務(wù)所做的改變
  2. 舉個(gè)栗子
    某個(gè)夜黑風(fēng)高的夜晚,小明豐富的夜生活開(kāi)始了,小明拿著工資卡去消費(fèi),pos機(jī)讀取卡的信息的時(shí)候有500,
    而此時(shí)小紅也正好在網(wǎng)上轉(zhuǎn)賬,把小明工資卡的500元轉(zhuǎn)到另一賬戶,并小明之前提交了事務(wù),當(dāng)小明扣款時(shí),
    系統(tǒng)檢查到小明的工資卡已經(jīng)沒(méi)有錢,扣款失敗,小明十分納悶,明明卡里有錢,為什么會(huì)說(shuō)余額不足,
    出現(xiàn)上述情況,即我們所說(shuō)的不可重復(fù)讀,兩個(gè)并發(fā)的事務(wù),“事務(wù)1:小明消費(fèi)”、“事務(wù)2:小紅網(wǎng)上轉(zhuǎn)賬”,事務(wù)1事先讀取了數(shù)據(jù),
    事務(wù)2緊接了更新了數(shù)據(jù),并提交了事務(wù),而事務(wù)1再次讀取該數(shù)據(jù)時(shí),數(shù)據(jù)已經(jīng)發(fā)生了改變,
    當(dāng)隔離級(jí)別設(shè)置為Read committed時(shí),避免了臟讀,但是可能會(huì)造成不可重復(fù)讀
  3. 示意圖


    image
  4. 備注
    Sql Server ,Oracle的默認(rèn)級(jí)別
    
  5. 示例代碼
    第一步窗口一(事務(wù)1)
    -- 事務(wù)1
    -- 1. 設(shè)置隔離級(jí)別為讀取已提交
    SET TX_ISOLATION = 'READ-COMMITTED';
    -- 2. 查看當(dāng)前連接的事務(wù)級(jí)別
    SELECT @@TX_ISOLATION;
    +----------------+
    | @@TX_ISOLATION |
    +----------------+
    | READ-COMMITTED |
    -- 3. 關(guān)閉自動(dòng)提交
    SET AUTOCOMMIT = 0;
    -- 4. 關(guān)閉自動(dòng)提交
    SELECT @@AUTOCOMMIT;
    -- 5.開(kāi)啟事務(wù)
    START TRANSACTION;
    -- 6.賬號(hào)余額-100
    UPDATE account
    SET account.money= money - 100
    WHERE aid = 1;
    
    第二步窗口二(事務(wù)2)
    -- 事務(wù)2
    -- 1. 設(shè)置隔離級(jí)別為讀取已提交
    SET TX_ISOLATION = 'READ-COMMITTED';
    -- 2. 查看當(dāng)前連接的事務(wù)級(jí)別
    SELECT @@TX_ISOLATION;
    -- 3. 關(guān)閉自動(dòng)提交
    SET AUTOCOMMIT = 0;
    -- 4. 關(guān)閉自動(dòng)提交
    SELECT @@AUTOCOMMIT;
     -- 5. 事務(wù)1 ******還沒(méi)有提交事務(wù)****
     -- 查詢賬戶信息
    BEGIN;
    SELECT  * FROM account WHERE aid = 1
    +-----+---------+--------+---------+
    | aid | card_no | name   | money   |
    +-----+---------+--------+---------+
    |   1 | 1       | 小明   | 1000.00 |
    +-----+---------+--------+---------+
    
    第三步窗口一(事務(wù)1)
    -- 7.提交事務(wù)
    COMMIT
    
    第四步窗口二(事務(wù)2)
    -- 5. 此時(shí)事務(wù)已經(jīng)提交 兩次查詢的結(jié)果不一致
    SELECT  * FROM account WHERE aid = 1
    COMMIT;
    +-----+---------+--------+--------+
    | aid | card_no | name   | money  |
    +-----+---------+--------+--------+
    |   1 | 1       | 小明   | 900.00 |
    +-----+---------+--------+--------+
    -- 相同的select語(yǔ)句,結(jié)果卻不一樣
    

3、Repeatable read

  1. 說(shuō)明
    當(dāng)用戶讀取某一范圍的數(shù)據(jù)行時(shí),另一個(gè)事務(wù)又在該范圍內(nèi)插入了新行,當(dāng)用戶再讀取該范圍的數(shù)據(jù)行時(shí)
  2. 舉個(gè)栗子
    小紅最近發(fā)現(xiàn)小明總是很晚回家并且經(jīng)常不接電話,于是小紅開(kāi)始查小明當(dāng)月信用卡的總消費(fèi)金額,
    消費(fèi)金額為50,而小明此時(shí)正好在收銀臺(tái)買單,消費(fèi)1000元,即新增了一條1000元的消費(fèi)記錄,并提交了事務(wù),
    隨后小紅將小明當(dāng)月信用卡消費(fèi)的明細(xì)打印了出來(lái),卻發(fā)現(xiàn)消費(fèi)總額為1050元,小紅很詫異,以為出現(xiàn)了幻覺(jué)
  3. 示例圖


    image
  4. 備注
    MySQL的默認(rèn)隔離級(jí)別
  5. 區(qū)別
    • 不可重復(fù)讀的重點(diǎn)是修改比如多次讀取一條記錄發(fā)現(xiàn)其中某些列的值被修改(但mysql由于MVCC機(jī)制并不會(huì)有),
    • 幻讀的重點(diǎn)在于新增或者刪除比如多次范圍讀取發(fā)現(xiàn)記錄增多或減少了。
  6. 示例代碼
    1. 第一步窗口一(事務(wù)1)
      -- 事務(wù)1
      -- 1. 查看當(dāng)前連接的事務(wù)級(jí)別
      SELECT @@TX_ISOLATION;
      +----------------+
      | @@TX_ISOLATION |
      +----------------+
      | READ-COMMITTED |
      -- 2. 關(guān)閉自動(dòng)提交
      SET AUTOCOMMIT = 0;
      -- 3. 關(guān)閉自動(dòng)提交
      SELECT @@AUTOCOMMIT;
      -- 4.開(kāi)啟事務(wù)
      START TRANSACTION;
      -- 5.賬號(hào)余額-100
      UPDATE account SET account.money= money - 100 WHERE aid = 1;
      
      第二步窗口二(事務(wù)2)
      -- 事務(wù)2
      -- 1. 查看當(dāng)前連接的事務(wù)級(jí)別
      SELECT @@TX_ISOLATION;
      -- 2. 關(guān)閉自動(dòng)提交
      SET AUTOCOMMIT = 0;
      -- 3. 關(guān)閉自動(dòng)提交
      SELECT @@AUTOCOMMIT;
       -- 查詢賬戶信息
      BEGIN;
      SELECT  * FROM account WHERE aid = 1
      +-----+---------+--------+---------+
      | aid | card_no | name   | money   |
      +-----+---------+--------+---------+
      |   1 | 1       | 小明   | 1000.00 |
      +-----+---------+--------+---------+
      
      第三步窗口一(事務(wù)1)
      -- 7.提交事務(wù)
      COMMIT
      
      第四步窗口二(事務(wù)2)
      -- 5. 此時(shí)事務(wù)已經(jīng)提交 兩次查詢的結(jié)果不一致
      SELECT  * FROM account WHERE aid = 1
      COMMIT;
      +-----+---------+--------+--------+
      | aid | card_no | name   | money  |
      +-----+---------+--------+--------+
      |   1 | 1       | 小明   | 1000.00 |
      +-----+---------+--------+--------+
      -- 相同的select語(yǔ)句,結(jié)果一樣
      
    2. 但幻讀還是問(wèn)題還是有(演示幻讀)
      第一步窗口一(事務(wù)1)
      -- 事務(wù)1
      --  1 開(kāi)始事務(wù)
      BEGIN;
      -- 2. 查詢
      SELECT *
      FROM account WHERE aid > 1;
      -- 查詢一條記錄
      
      image

      第二步窗口二(事務(wù)2)
      -- 事務(wù)2
      BEGIN;
        INSERT INTO account(CARD_NO, NAME, MONEY) VALUE ('99999', '老王', 0.00);
        INSERT INTO account(CARD_NO, NAME, MONEY) VALUE ('5555', '櫻櫻是誰(shuí)', 10.00);
      COMMIT
      -- 并且提交
      
      第三步窗口一(事務(wù)1)
      -- 3.批量更新數(shù)據(jù)
      --  MVCC只對(duì)讀有效,對(duì)寫操作無(wú)效,由于update是寫操作,
      UPDATE account
      SET money = 0.00
      WHERE aid > 1;
      -- 4. 再次查詢出現(xiàn)幻讀
      SELECT *
      FROM account
      WHERE aid > 1;
      COMMIT;
      
  7. 說(shuō)明
    從原理上看,可重復(fù)讀是靠MVCC(多版本并發(fā)控制)保證的,該模式下,保證事務(wù)只能讀取到當(dāng)前事務(wù)開(kāi)啟之前已經(jīng)提交的事務(wù)進(jìn)行的修改以及當(dāng)前事務(wù)本身對(duì)數(shù)據(jù)的修改

4、Serializable(串行)(了解)

  1. 說(shuō)明
    最高級(jí)別:防止上述3種情況,事務(wù)串行執(zhí)行,慎用
    這是最高的隔離級(jí)別,它通過(guò)強(qiáng)制事務(wù)排序,使之不可能相互沖突,從而解決不讀臟,可重復(fù)讀,不可幻讀。
    簡(jiǎn)言之,它是在每個(gè)讀的數(shù)據(jù)行上加上共享鎖。在這個(gè)級(jí)別,可能導(dǎo)致大量的超時(shí)現(xiàn)象和鎖競(jìng)爭(zhēng),并發(fā)性能最差,在分布式事務(wù)中可能會(huì)被用到
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容