mysql交易隔離等級以及有問題的讀取(髒讀,不可重複讀取,幻象讀)

來源:互聯網
上載者:User

標籤:

1.事務裡一些有問題的讀取:髒讀,不可重複讀取,幻象讀

 

髒讀 (dirty read)事務T1更新了一行記錄的內容,但是並沒有提交所做的修改。事務T2讀取更新後的行,然後T1執行復原操作,取消了剛才所做的修改。現在T2所讀取的行就無效了。

 

不可重複讀取 (nonrepeatable read)事務T1讀取一行記錄,緊接著事務T2修改 了T1剛才讀取的那一行記錄。然後T1又再次讀取這行記錄,發現與剛才讀取的結果不同。這就稱為“不可重複”讀,因為T1原來讀取的那行記錄已經發生了變化。

 

幻像讀取 (phantom read)事務T1讀取一條指定的WHERE子句所返回的結果集。然後事務T2新插入 一行記錄,這行記錄恰好可以滿足T1所使用的查詢條件中的WHERE 子句的條件。然後T1又使用相同的查詢再次對錶進行檢索,但是此時卻看到了事務T2剛才插入的新行。這個新行就稱為“幻像”,因為對T1來說這一行就像突 然出現的一樣。

 

2.事務的隔離等級

從層級低到高依次為:

READ UNCOMMITTED 幻像讀、不可重複讀取和髒讀都允許。

READ COMMITTED 允許幻像讀、不可重複讀取,但不允許髒讀。

REPEATABLE READ 允許幻像讀,但不允許不可重複讀取和髒讀。InnoDB預設層級

SERIALIZABLE 幻像讀、不可重複讀取和髒讀都不允許。

 

但是InnoDB的可重複讀隔離等級和其他資料庫的可重複讀是有區別的,不會造成幻象讀(phantom read)。

 

ORACLE資料庫支援 READ COMMITTED 和 SERIALIZABLE ,不支援 READ UNCOMMITTED 和 REPEATABLE READ 。

 

3.測試:

 

1)並發更新 ,表tab1 的一條記錄id=1 num=1,兩個session分別執行事務1,2

分別輸入下面的語句

事務1 (session1) :

           start transaction;

           update tab1 set num=num+1 where id=1;

=========

一條記錄被更新,select發現num=2;

 

事務2 (session2):

           start transaction;

           update tab1 set num=num+1 where id=1;

=========

事務2會被阻塞,然後session1輸入commit;提交事務1。此時事務2更新成功。

 

session1 select一下會發現num還是2(不允許髒讀 );session2 select 一下 num 為3(update可以得到最新提交過的資料然後更新,但是如果沒有update,一直是select 的話select得到的num一直是1 ),然後commit;

session1 select 發現num為3 ,session2 select 發現num為3;

 

所以,事務中update是有行寫鎖(獨佔鎖定)的,不會發生: 髒讀和不可重複讀取(對於自身有update的事務,update之後是可以讀到最新資料的,這屬於例外?^_^ ),

 

2)關於幻象讀 ,innodb預設交易隔離等級是不會出現的;摘自網上,測試通過:

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)

 

 

4.最後,現在應該知道資料庫並發控制並不複雜,交給資料庫的事務就行,mysql 選用innodb引擎,不會出現:“不可重複讀取”(就是在事務1進行資料修改的時候,事務2讀取的資料是沒修改 之前的資料,事務1提交的時候,事務2再次讀取的時候得到的是修改後的資料,單個事務內所讀資料不一致),“髒讀”,“幻象讀”;

 關於innodb鎖機制的詳細解釋,參見《mysql手冊》-“15.2.10 .  InnoDB 事務模型和鎖定”。

mysql交易隔離等級以及有問題的讀取(髒讀,不可重複讀取,幻象讀)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.