1. 程式人生 > 其它 >MySQL隔離級別(幻讀)

MySQL隔離級別(幻讀)

技術標籤:基礎mysql

Mysql 事務的基本瞭解

ACID
1:事務的概念
什麼是事務呢?事務是指單個邏輯單元完成一些列操作,它要麼全部執行成功,要麼就失敗。事務處理可確保只有事務單元的操作。否則就不會擁有永久面向資料的更新資源,一個邏輯工作單元要想成為事務,那麼他就必須要擁有事務的特性。

2:事務的用途
事務主要處理大量操作且資料複雜度比較高。這裡舉一個生活中常見例子,比如銀行轉賬等。
3:ACID的特性
1:原子性
一個事務中的所有操作,他必須要具有原子性,在這個事務的執行過程中,它要麼全部執行成功,要麼就失敗。而不會停留在某個環節。事務在執行過程中,他會被rollback到事務的執行狀態。

2:一致性
事務在操作前後,資料庫的完整都不會進行破壞。
3:隔離性
同一時間,只是允許一個事務對一條的進行操作。不同事務之間的操作是互不受影響的。
4:永續性
在事務操作完成後,對物理層面的影響是永久的,事務commit後,它會把所有的操作更新都會儲存到資料庫中的。且不能進行rollback。

事物隔離級別
讀未提交(Read Uncommitted):即使一個事務的更新語句沒有提交,但是別的事務可以讀到這個改變。會導致以上幾種異常情況都可能出現,極易出錯,沒有安全性可言,基本不會使用。
讀已提交(Read Committed):一個事務只能看到其他事務的已經提交的更新,看不到未提交的更新,這是大多數資料庫的預設隔離級別,如Oracle,Sqlserver。

可重複讀(Repeatable Read):一個事務中進行兩次或多次相同的資料庫讀操作,得到的結果是一樣的。這是Mysql資料庫的預設隔離級別。
序列化(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);

比如:

  sqlselect * from name where id = 5 for update#提交
  commit;

然而我們執行這個語句後,就問題來了
當我們這個事務提交後,是鎖住id為5的記錄,還是鎖住了這個表的資料呢?
不妨,我們來測試一下。
假如我們自定義id為5的,當只是鎖住id為5的記錄

select * from test where id = 5 for update;

#結果555update  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;