資料庫的事物隔離級別

2022-06-15 06:36:13 字數 4223 閱讀 5537

sql標準定義了四種隔離級別,如下:

在各個級別上被禁止出現的現象是:

髒讀乙個事務讀取了另乙個並行未提交事務寫入的資料。

不可重複讀

乙個事務重新讀取之前讀取過的資料,發現該資料已經被另乙個事務(在初始讀之後提交)修改。

幻讀乙個事務重新執行乙個返回符合乙個搜尋條件的行集合的查詢, 發現滿足條件的行集合因為另乙個最近提交的事務而發生了改變。

序列化異常

成功提交一組事務的結果與這些事務所有可能的序列執行結果都不一致。

以pg為例,進行測試,先檢視預設的隔離級別

psql (12.0 (debian 12.0

-2.pgdg100+1))

type "help"

forhelp.

postgres

=# show transaction_isolation;

transaction_isolation

-----------------------

read

committed

(1 row)

讀未提交

表示可以讀到其他會話未提交的資料(postgresql不支援)。

讀已提交

表示可以讀到其他會話已提交的資料。

1.建立一張表為test,插入一條記錄

postgres=# create

table test(id int,name char(10

));create

table

postgres

=# insert

into test values(1,'

tom'

);insert

01

2.在會話1中開啟事務進行查詢

postgres=# begin

;begin

postgres

=# select

*from

test;

id |name

----+------------1|

tom(

1 row)

3.在會話2中開啟事務進行更新

postgres=# begin

;begin

postgres

=# update test set name=

'jack

'where id=1;

update

1postgres

=#

4.此時在會話2中還沒有關閉事務,在會話1中進行查詢

postgres=# select

*from

test;

id |name

----+------------1|

tom(

1 row)

5.發現會話1中的記錄並沒有進行改變。當提交會話2中的事務,在會話1中進行查詢值已經改變

postgres=# update test set name=

'jack

'where id=1;

update

1postgres

=# commit

;commit

再次查詢

postgres=# select

*from

test;

id |name

----+------------1|

jack

(1 row)

可重複讀

表示在乙個事務中,執行同一條sql,讀到的是同樣的資料(即使被讀的資料可能已經被其他會話修改並提交)。

先修改隔離級別

postgres=# set default_transaction_isolation=

'repeatable read';

setpostgres

=# show transaction_isolation;

transaction_isolation

-----------------------

repeatable

read

(1 row)

在會話1中開啟可重複讀事務,進行查詢

postgres=# select

*from

test;

id |name

----+------------1|

jack

(1 row)

在會話2中進行更新操作

postgres=# update test set name='pg

'where id=1;

update

1

在會話1中進行查詢,發現會話1中的記錄沒有因為會話2的提交而變化

postgres=# select

*from

test;

id |name

----+------------1|

jack

(1 row)

在會話1中進行提交,再查詢,發現會話1中的記錄變化了

postgres=# commit

;commit

postgres

=# select

*from

test;

id |name

----+------------1|

pg(1 row)

序列化表示並行事務模擬序列執行,違反序列執行規則的事務,將回滾。

1.在會話 1中開啟事務序列

postgres=# begin

transaction

isolation

level

serializable

;begin

2.在會話2中開啟事務序列

postgres=# begin

transaction

isolation

level

serializable

;begin

3.在會話1中進行插入操作

postgres=# insert

into test select

*from

test;

insert01

postgres

=# select

*from

test;

id |name

----+------------1|

pg 1|

pg(2 rows)

4.在會話2中進行插入操作

postgres=# insert

into test select

*from

test;

insert01

postgres

=# select

*from

test;

id |name

----+------------1|

pg 1|

pg(2 rows)

5.提交會話1中的事務,能夠正常提交,進行查詢能夠查到插入的記錄

postgres=# commit

;commit

postgres

=# select

*from

test;

id |name

----+------------1|

pg 1|

pg(2 rows)

6.當提交會話2的事務時會報錯

postgres=# commit

;error: could

not serialize access due to

read

/write dependencies among transactions

detail: reason code: canceled

on identification as a pivot, during commit

attempt.

hint: the

transaction might succeed if retried.

資料庫事物隔離級別

資料庫事物的隔離級別有4個,由低到高依次為 1.read uncommitted 兩個併發的事務,事務b讀取了事物a尚未提交的資料,出現髒讀。2.read committed 事務a事先讀取了資料,事務b緊接更新了資料,並提交了事務,而事務a再次讀取該資料時,資料已發生了改變,即所說的不可重複讀。3...

資料庫事物隔離級別

事物隔離級別 1 序列化 serializable 單位時間,只有乙個事物,強制事物排序,並行度低,效能差 2 可重複讀 repeatable read 讀操作可以並行,同乙個事物裡,所有讀操作的結果都是事物開始時的狀態 一致性 但可以增加新的記錄,mysql 預設事物隔離級別 3 讀已提交 rea...

資料庫事物的隔離級別

資料庫事務的隔離級別有4個,由低到高依次為read uncommitted read committed repeatable read serializable,這四個級別可以逐個解決髒讀 不可重複讀 幻讀這幾類問題。可能出現 不會出現 髒讀不可重複讀 幻讀read uncommitted rea...