天天看點

[InnoDB系列] - 執行個體解析Innodb的隔離級别以及鎖模式

作/譯者:葉金榮(Email:

[InnoDB系列] - 執行個體解析Innodb的隔離級别以及鎖模式

),來源:http://imysql.cn,轉載請注明作/譯者和出處,并且不能用于商業用途,違者必究。

1、隔離級别為:READ COMMITTED

READ COMMITTED

一個有些象Oracle的隔離級别。所有SELECT ... FOR UPDATE和SELECT ... LOCK IN SHARE

MOD語句僅鎖定索引記錄,而不鎖定記錄前的間隙,因而允許随意緊挨着已鎖定的記錄插入新記錄。UPDATE和DELETE語句使用一個帶唯一搜尋條件的唯一的索引僅鎖定找到的索引記錄,而不包括記錄前的間隙。在範圍類型UPDATE和DELETE語句,InnoDB必須對範圍覆寫的間隙設定next-key鎖定或間隙鎖定以及其它使用者做的塊插入。這是很必要的,因為要讓MySQL複制和恢複起作用,“幽靈行”必須被阻止掉。

持續讀行為如同在Oracle中:即使在同一事務内, 每個持續讀設定并讀取它自己的新快照。請參閱15.2.10.4節,“持續非鎖定讀”

看看實測步驟:

session 1

session 2

begin

select * from v where id=1;

| id  

| name   |

|   

1 | name11 |

select * from v where id=1 lock in share

mode;

session1和sesssion2請求的都是共享鎖,不會互斥,是以無需等待。

select * from v where id=1 for update;

這個時候,由于session2發起了lock in share mode,需要請求一個共享鎖,和for update所需要的排它鎖是互斥的,是以session1需要等待session2送出或復原才能繼續。

commit;

select * from v where id =1 for update;

或者

select * from v where id =1 lock in share

update v set name = 'name 2' where id=1;

session1首先發起了一個select ..for update請求,會對該記錄加一個排它鎖,是以session2的請求會被等待,直到session1送出或者復原。

1 | name 2 |

select * from v where id =1;

可以看到,如果隻是發起最簡單的select請求,則傳回的結果是session2發生時看到的快照;如果發起一個select…for update或select..lock in share mode,則可以看到最新的快照。

這是因為select…for update或select…lock share mode會取得最新快照,并且請求加一個排它或者共享next-key鎖。而普通的select查詢不會請求加任何鎖。

update v set name = ‘name 1’ where id =1;

1 | name 1 |

可以看到session2送出後的最新結果。

2、隔離級别為:REPEATABLE READ

REPEATABLE READ

這是InnoDB的預設隔離級别。帶唯一搜尋條件使用唯一索引的SELECT ... FOR UPDATE, SELECT ... LOCK IN

SHARE MODE, UPDATE

和DELETE語句隻鎖定找到的索引記錄,而不鎖定記錄前的間隙。用其它搜尋條件,這些操作采用next-key鎖定,用next-key鎖定或者間隙鎖定鎖住搜尋的索引範圍,并且阻止其它使用者的新插入。

在持續讀中,有一個與之前隔離級别重要的差别:在這個級别,在同一事務内所有持續讀讀取由第一次讀所确定的同一快照。這個慣例意味着如果你在同一事務内發出數個無格式SELECT語句,這些SELECT語句對互相之間也是持續的,請參閱15.2.10.4節,“持續非鎖定讀”。 

begin;

update v set name='name 2' where id=1;

這個時候,不管是select…lock in

share mode還是select…for update,得到的結果都是session 1更新後送出的資料。

update v set name = 'name 1' where id=1;

select * from v where id=1 ;

關于鎖,摘取手冊中的幾條,更具體的請看mysql手冊,"存儲引擎和表類型" => "在InnoDB中不同SQL語句設定的鎖定" 這節。

· SELECT ...

FROM是一個持續讀,讀取資料庫的快照并且設定不鎖定,除非事務隔離級别被設為SERIALIZABLE。對于

SERIALIZABLE級别,這個設定對它遇到的索引記錄設定共享的next-key鎖定。

· SELECT ... FROM ... LOCK IN SHARE

MODE對讀遇到的所有索引記錄設定共享的next-key鎖定。

· SELECT ... FROM ... FOR

UPDATE對讀遇到的所有索引記錄設定獨占的next-key鎖定。

本文出自 “MySQL中文網”部落格 http://www.imysql.cn/