數據庫隔離級別詳解

  之前,我們有講過數據庫的索引,鏈接爲 數據庫索引詳解 今天,我們將講解數據庫的隔離級別。

一、隔離級別的種類與分別可以解決的問題:

  事務的隔離級別分爲4個,即 讀未提交(read uncommitted)、讀已提交(read committed)、可重複讀(Repeatable read)、可串行化(Serializable)

 oracle默認的隔離級別爲 讀已提交。mysql的默認隔離級別爲 可重複讀。

 其中可以解決的問題如下表:

  簡單來說:

  髒讀即爲session A讀取到了session B中未提交的數據

  不可重複讀即爲session A讀取到了session B提交的數據,即前後session A讀取的數據不一致

  幻讀即爲session A讀取到了session B insert的數據。

 

二、隔離級別的設置與查詢:

 1、設置隔離級別:

  設置隔離級別分爲設置全局的隔離級別與設置當前的隔離級別

  全局設置,已存在的session不會生效,以後的新session會生效(以讀未提交舉例):

   set global transaction isolation level read uncommitted;

  單獨設置當前連接:

    set session transaction isolation level read uncommitted;

 2 、查看當前隔離級別:

   select @tx_isolation;

 

三、事務隔離級別的測試:

有一個goods表,裏面有id、count(商品數量)、brandId(品牌id)

CREATE TABLE `goods` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`count` int(11) DEFAULT '0',

`brandId` int(11) DEFAULT '0',

PRIMARY KEY (`id`),

KEY `idx_brandId` (`brandId`)

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf-8;

1、髒讀(設置隔離級別爲讀未提交):

  髒讀爲讀到其它事務未提交的數據:

A B

select * from goods where id = 1;

返回1

 
  update goods set count = 2 where id = 1;

select * from goods where id = 1;

返回2

 
  commit;

2、不可重複讀(設置隔離級別爲 讀已提交)

  不可重複讀爲讀到其它數據已提交的數據,即前後查詢數據不一致

A B

select * from goods where id = 1;

返回1

 
  update goods set count = 2 where id = 1;

select * from goods where id = 1;

返回1

 
  commit;

select * from goods where id = 1;

返回2

 

3、幻讀(設置隔離級別爲 可重複讀):

  幻讀爲讀到別人已提交的寫入數據庫的數據。

  幻讀與不可重複讀的區別爲幻讀爲讀到新插入的數據(insert),而不可重複讀主要是更改與刪除(update、delete)。

  即不可重複讀前後被其它session update、delete的數據沒有問題,不會有變化,但是其它session insert的可能有變化。

A B

select * from goods where brandId = 1;

返回有id爲1,2的兩條

 
  insert into goods (count,brandId) values (3, 1);
  commit;

select * from goods where brandId = 1;

返回有id爲1,2,3的三條

 

當隔離級別爲 可串行化 的時候則不會出現上述問題。

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章