MySQL 中 InnoDB 存儲(chǔ)引擎提供了事務(wù)隔離級(jí)別,其中包括四種:讀未提交,讀提交,可重復(fù)讀和串行化。
今天我們討論的是其中兩種隔離級(jí)別:讀提交和可重復(fù)讀。
讀提交(Read Committed)
讀提交是 InnoDB 的默認(rèn)事務(wù)隔離級(jí)別,并且是大部分應(yīng)用所使用的級(jí)別。讀提交的意思是一個(gè)事務(wù)只能看到已經(jīng)提交的事務(wù)所做的修改。如果一個(gè)事務(wù)正在進(jìn)行中,而且對(duì)某個(gè)數(shù)據(jù)行進(jìn)行了修改,那么在該事務(wù)提交之前,其他事務(wù)是看不到這個(gè)修改的。
按照正常的操作流程,讀提交的行為規(guī)則如下:
-- 啟用讀提交事務(wù)隔離級(jí)別 SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; -- 創(chuàng)建一個(gè)示例表 CREATE TABLE test_table ( id INT PRIMARY KEY, name VARCHAR(16) ); -- 在一個(gè)事務(wù)中插入數(shù)據(jù)并提交 START TRANSACTION; INSERT INTO test_table (id, name) VALUES (1, 'Hello'); COMMIT; -- 在另一個(gè)事務(wù)中查詢數(shù)據(jù),此時(shí)只能查詢到已經(jīng)提交的數(shù)據(jù) START TRANSACTION; SELECT id, name FROM test_table WHERE id = 1; COMMIT;
可重復(fù)讀(Repeatable Read)
可重復(fù)讀是比較常用的事務(wù)隔離級(jí)別之一,在 MySQL 中也被稱為默認(rèn)的事務(wù)隔離級(jí)別。與讀提交不同,可重復(fù)讀允許一個(gè)事務(wù)內(nèi)多次讀取同一數(shù)據(jù)行時(shí),保持這些數(shù)據(jù)的一致性,即在一個(gè)事務(wù)中第一次讀取某個(gè)數(shù)據(jù)行時(shí),該數(shù)據(jù)行所做的任何修改對(duì)后續(xù)讀取都是不可見的。
按照正常的操作流程,可重復(fù)讀的行為規(guī)則如下:
-- 啟用可重復(fù)讀事務(wù)隔離級(jí)別 SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; -- 在一個(gè)事務(wù)中查詢數(shù)據(jù)并提交 START TRANSACTION; SELECT id, name FROM test_table WHERE id = 1; COMMIT; -- 在另一個(gè)事務(wù)中修改數(shù)據(jù)時(shí),之前查詢的數(shù)據(jù)行不受影響 START TRANSACTION; UPDATE test_table SET name = 'World' WHERE id = 1; COMMIT; -- 再次查詢數(shù)據(jù)時(shí),仍能查詢到與之前一致的數(shù)據(jù) START TRANSACTION; SELECT id, name FROM test_table WHERE id = 1; COMMIT;
總的來說,在實(shí)際應(yīng)用中根據(jù)業(yè)務(wù)需求選擇合適的事務(wù)隔離級(jí)別是很重要的,不當(dāng)?shù)倪x擇可能導(dǎo)致數(shù)據(jù)不一致或者性能下降。