MySQL隔離級別(幻讀)
阿新 • • 發佈:2021-01-17
Mysql 事務的基本瞭解
ACID
1:事務的概念
什麼是事務呢?事務是指單個邏輯單元完成一些列操作,它要麼全部執行成功,要麼就失敗。事務處理可確保只有事務單元的操作。否則就不會擁有永久面向資料的更新資源,一個邏輯工作單元要想成為事務,那麼他就必須要擁有事務的特性。
2:事務的用途
事務主要處理大量操作且資料複雜度比較高。這裡舉一個生活中常見例子,比如銀行轉賬等。
3:ACID的特性
1:原子性
一個事務中的所有操作,他必須要具有原子性,在這個事務的執行過程中,它要麼全部執行成功,要麼就失敗。而不會停留在某個環節。事務在執行過程中,他會被rollback到事務的執行狀態。
事務在操作前後,資料庫的完整都不會進行破壞。
3:隔離性
同一時間,只是允許一個事務對一條的進行操作。不同事務之間的操作是互不受影響的。
4:永續性
在事務操作完成後,對物理層面的影響是永久的,事務commit後,它會把所有的操作更新都會儲存到資料庫中的。且不能進行rollback。
事物隔離級別
讀未提交(Read Uncommitted):即使一個事務的更新語句沒有提交,但是別的事務可以讀到這個改變。會導致以上幾種異常情況都可能出現,極易出錯,沒有安全性可言,基本不會使用。
讀已提交(Read Committed):一個事務只能看到其他事務的已經提交的更新,看不到未提交的更新,這是大多數資料庫的預設隔離級別,如Oracle,Sqlserver。
序列化(Serializable):事務執行的時候不允許別的事務併發執行,而是完全序列化的讀,只要存在讀就禁止寫,但可以同時讀,消除了幻讀。這是事務隔離的最高級別,雖然最安全,但是效率太低,一般不會用。
而MySQL的隔離級別為可重複讀。
事務的實現方式
原子性 永續性 一致性都是通過資料庫的redo log(重做日誌,用來保證原子性和永續性)和undo log(回滾日誌,事務的一致性)去完成的。而事物的隔離性則是通過mysql自身的鎖機制去完成。
幻讀
我們這裡先隨便建立一個表
CREATE TABLE t_demo(
id int(11) NOT NULL,
d int(11) DEFAULT NULL,
d_1 int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `d_1` (`d_1`)
);
insert into t_demo values(0,0,0),(1,1,1),
(2,2,2),(3,3,3),(4,4,4),(5,5,5);
比如:
sql:select * from name where id = 5 for update;
#提交
commit;
然而我們執行這個語句後,就問題來了
當我們這個事務提交後,是鎖住id為5的記錄,還是鎖住了這個表的資料呢?
不妨,我們來測試一下。
假如我們自定義id為5的,當只是鎖住id為5的記錄
select * from test where id = 5 for update;
#結果
(5,5,5)
update t_demo set d_1 = 5 where id = 0;
#結果
(0,0,5) (5,5,5)
insert into t_demo VALUES(6,6,5);
select * from t_demo where d_1=5 for update;
(0,0,5)(5,5,5)(6,6,5)
當事務進行操作的時候,我們上面查詢的是id為5的資料。當我們使用鎖定讀的時候看一看到其他的資料。因此這一情況是幻讀。
解決幻讀的方案,我們可以設定事務的自動提交;
#首先先檢視事物的隔離級別
select @@tx_isolation;
#然後設定自動提交
set autocommit;