實踐理解Mysql事務隔離級別之可重復讀


可重復讀

Mysql的事務隔離級別,默認是可重復讀(repeatable-read)。

以下通過具體的sql操作去理解可重復讀。

建表

CREATE DATABASE test;

USE test;

CREATE TABLE `t_order` (
  `fid` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵,自增id',
  `forder_id` varchar(35) NOT NULL COMMENT '訂單號,唯一',
  `fpay_status` varchar(15) DEFAULT '00' COMMENT '00:未支付,01:支付成功,02:支付失敗,03:已下單,04:申請退款,05:退款成功,06:退款失敗,10:訂單關閉',
  PRIMARY KEY (`fid`),
  UNIQUE KEY `forder_id` (`forder_id`)
  )   ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='訂單表';
	
SELECT * FROM t_order;

多個事務操作

如果使用的是navicat,可以新建兩個"查詢"窗口,模擬A、B兩個事務。

1.在兩個窗口,分別執行以下語句,開啟事務:

BEGIN;

2.查詢數據:

SELECT * FROM t_order WHERE forder_id='abc';

結果如下:

3.在A事務中,執行update語句,然后再次查詢:

UPDATE t_order SET fpay_status='01' WHERE forder_id='abc' AND fpay_status='00';

SELECT * FROM t_order WHERE forder_id='abc';

結果如下:

在A事務中,執行update后,fpay_status變為'01'

4.在B事務中,查詢數據,結果如下:

由於A事務還沒有提交,在可重復讀的事務隔離級別下,B事務中的數據還是初始的值'00'。

接着,在B事務中,執行update語句,如下:

UPDATE t_order SET fpay_status='01' WHERE forder_id='abc' AND fpay_status='00';

發現B事務會阻塞,原因是A事務執行update語句時加了行鎖。

一段時間后,B事務會超時。

重新開啟B事務:

BEGIN;

5.提交A事務:

COMMIT;

然后,在B事務中查詢,結果如下:

發現B事務中的fpay_status還是初始的值'00',這是因為:

在可重復讀的事務隔離級別下,讀取的是快照數據,總是讀取當前事務開始時的行數據版本。

6.提交B事務。

COMMIT;

然后再次查詢:

提交事務后,查詢到的就是最新的數據了,fpay_status為'01'。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM