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=# create2.在會話1中開啟事務進行查詢table test(id int,name char(10
));create
table
postgres
=# insert
into test values(1,'
tom'
);insert
01
postgres=# begin3.在會話2中開啟事務進行更新;begin
postgres
=# select
*from
test;
id |name
----+------------1|
tom(
1 row)
postgres=# begin4.此時在會話2中還沒有關閉事務,在會話1中進行查詢;begin
postgres
=# update test set name=
'jack
'where id=1;
update
1postgres
=#
postgres=# select5.發現會話1中的記錄並沒有進行改變。當提交會話2中的事務,在會話1中進行查詢值已經改變*from
test;
id |name
----+------------1|
tom(
1 row)
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=在會話1中開啟可重複讀事務,進行查詢'repeatable read';
setpostgres
=# show transaction_isolation;
transaction_isolation
-----------------------
repeatable
read
(1 row)
postgres=# select在會話2中進行更新操作*from
test;
id |name
----+------------1|
jack
(1 row)
postgres=# update test set name='pg在會話1中進行查詢,發現會話1中的記錄沒有因為會話2的提交而變化'where id=1;
update
1
postgres=# select在會話1中進行提交,再查詢,發現會話1中的記錄變化了*from
test;
id |name
----+------------1|
jack
(1 row)
postgres=# commit序列化表示並行事務模擬序列執行,違反序列執行規則的事務,將回滾。;commit
postgres
=# select
*from
test;
id |name
----+------------1|
pg(1 row)
1.在會話 1中開啟事務序列
postgres=# begin2.在會話2中開啟事務序列transaction
isolation
level
serializable
;begin
postgres=# begin3.在會話1中進行插入操作transaction
isolation
level
serializable
;begin
postgres=# insert4.在會話2中進行插入操作into test select
*from
test;
insert01
postgres
=# select
*from
test;
id |name
----+------------1|
pg 1|
pg(2 rows)
postgres=# insert5.提交會話1中的事務,能夠正常提交,進行查詢能夠查到插入的記錄into test select
*from
test;
insert01
postgres
=# select
*from
test;
id |name
----+------------1|
pg 1|
pg(2 rows)
postgres=# commit6.當提交會話2的事務時會報錯;commit
postgres
=# select
*from
test;
id |name
----+------------1|
pg 1|
pg(2 rows)
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...