四,隔離級別對併發的控制
下表是各隔離級別對各種異常的控制能力。
lu丟失更新
dr髒讀
nrr非重複讀
slu二類丟失更新
pr幻像讀
未提交讀 ruyy
yyy提交讀 rcnn
yyy可重複讀 rrnn
nny序列讀 snn
nnn
順便舉一小例。
ms_sql:
--事務一
set transaction isolation level serializable
begin tran
insert into test values('***')
--事務二
set transaction isolation level read committed
begin tran
select * from test
--事務三
set transaction isolation level read uncommitted
begin tran
select * from test
在查詢分析器中執行事務一後,分別執行事務二,和三。結果是事務二會等待,而事務三則會執行。
oracle:
--事務一
set transaction isolation level serializable;
insert into test values('***');
select * from test;
--事務二
set transaction isolation level read committed--oracle預設級別
select * from test
執行事務一後,執行事務二。結果是事務二只讀出原有的資料,無視事務一的插入操作。
mysql
檢視innodb系統級別的事務隔離級別:
以下為引用的內容:
mysql> select @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| repeatable-read |
+-----------------------+
1 row in set (0.00 sec)
檢視innodb會話級別的事務隔離級別:
以下為引用的內容:
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| repeatable-read |
+-----------------+
1 row in set (0.00 sec)
修改事務隔離級別:
以下為引用的內容:
mysql> set global transaction isolation level read committed;
query ok, 0 rows affected (0.00 sec)
mysql> set session transaction isolation level read committed;
query ok, 0 rows affected (0.00 sec)
innodb的可重複讀隔離級別和其他資料庫的可重複讀是有區別的,不會造成幻象讀(phantom read),所謂幻象讀,就是同乙個事務內,多次select,可以讀取到其他session insert並已經commit的資料。下面是乙個小的測試,證明innodb的可重複讀隔離級別不會造成幻象讀。測試涉及兩個session,分別為 session 1和session 2,隔離級別都是repeateable read,關閉autocommit
以下為引用的內容:
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| repeatable-read |
+-----------------+
1 row in set (0.00 sec)
mysql> set autocommit=off;
query ok, 0 rows affected (0.00 sec)
session 1 建立表並插入測試資料
mysql> create table test(i int) engine=innodb;
query ok, 0 rows affected (0.00 sec)
mysql> insert into test values(1);
query ok, 1 row affected (0.00 sec)
session 2 查詢,沒有資料,正常,session1沒有提交,不允許髒讀
mysql> select * from test;
empty set (0.00 sec)
session 1 提交事務
mysql> commit;
query ok, 0 rows affected (0.00 sec)
session 2 查詢,還是沒有資料,沒有產生幻象讀
mysql> select * from test;
empty set (0.00 sec)
以上試驗版本:
mysql> select version();
+-------------------------+
| version() |
+-------------------------+
| 5.0.37-community-nt-log |
+-------------------------+
1 row in set (0.00 sec)
五、併發一致性問題的解決辦法
1 封鎖(locking)
封鎖是實現併發控制的乙個非常重要的技術。所謂封鎖就是事務t在對某個資料物件例如表、記錄等操作之前,先向系統發出請求,對其加鎖。加鎖後事務t就對該 資料物件有了一定的控制,在事務t釋放它的鎖之前,其它的事務不能更新此資料物件。 基本的封鎖型別有兩種:排它鎖(exclusive locks 簡記為x鎖)和共享鎖(share locks 簡記為s鎖)。
排它鎖又稱為寫鎖。若事務t對資料物件a加上x鎖,則只允許t讀取和修改a,其它任何事務都不能再對a加任何型別的鎖,直到t釋放a上的鎖。這就保證了其它事務在t釋放a上的鎖之前不能再讀取和修改a。
共享鎖又稱為讀鎖。若事務t對資料物件a加上s鎖,則其它事務只能再對a加s鎖,而不能加x鎖,直到t釋放a上的s鎖。這就保證了其它事務可以讀a,但在t釋放a上的s鎖之前不能對a做任何修改。
2 封鎖協議
在 運用x鎖和s鎖這兩種基本封鎖,對資料物件加鎖時,還需要約定一些規則,例如應何時申請x鎖或s鎖、持鎖時間、何時釋放等。我們稱這些規則為封鎖協議 (locking protocol)。對封鎖方式規定不同的規則,就形成了各種不同的封鎖協議。下面介紹**封鎖協議。**封鎖協議分別在不同程度上解決了丟失的修改、不 可重複讀和讀"髒"資料等不一致性問題,為併發操作的正確排程提供一定的保證。下面只給出**封鎖協議的定義,不再做過多**。
1 級封鎖協議是:事務t在修改資料r之前必須先對其加x鎖,直到事務結束才釋放。事務結束包括正常結束(commit)和非正常結束(rollback)。 1級封鎖協議可防止丟失修改,並保證事務t是可恢復的。在1級封鎖協議中,如果僅僅是讀資料不對其進行修改,是不需要加鎖的,所以它不能保證可重複讀和不 讀"髒"資料。
2級封鎖協議是:1級封鎖協議加上事務t在讀取資料r之前必須先對其加s鎖,讀完後即可釋放s鎖。2級封鎖協議除防止了丟失修改,還可進一步防止讀"髒"資料。
3級封鎖協議是:1級封鎖協議加上事務t在讀取資料r之前必須先對其加s鎖,直到事務結束才釋放。3級封鎖協議除防止了丟失修改和不讀'髒'資料外,還進一步防止了不可重複讀。
六、一般處理併發問題時的步驟:
1、開啟事務。
2、申請寫許可權,也就是給物件(表或記錄)加鎖。
3、假如失敗,則結束事務,過一會重試。
4、假如成功,也就是給物件加鎖成功,防止其他使用者再用同樣的方式開啟。
5、進行編輯操作。
6、寫入所進行的編輯結果。
7、假如寫入成功,則提交事務,完成操作。
8、假如寫入失敗,則回滾事務,取消提交。
9、(7.8)兩步操作已釋放了鎖定的物件,恢復到操作前的狀態。
(array7**:
資料庫事務隔離級別與鎖
四,隔離級別對併發的控制 下表是各隔離級別對各種異常的控制能力。lu丟失更新 dr髒讀 nrr非重複讀 slu二類丟失更新 pr幻像讀 未提交讀 ruyy yyy提交讀 rcnn yyy可重複讀 rrnn nny序列讀 snn nnn 順便舉一小例。ms sql 事務一 set transactio...
資料庫鎖和事務隔離級別
建立表account create table account id int not null auto increment,name varchar 255 default null,balance int default null,primary key id engine innodb def...
資料庫 事務與隔離級別
事務概述 redo log概述 undo log概述 事務控制語句 配置引數 控制語句 事務隔離級別 隔離級別簡介 mvcc併發控制 鎖型別簡介 事務是作為單個邏輯操作單元的一系列操作。事務可以包含一條或多條sql語句,所有的語句被當做乙個操作單元,要麼全部成功 要麼全部失敗 即作為乙個原子操作 資...