事務的隔離性

2022-05-21 08:34:04 字數 2923 閱讀 1673

事務有四大特性:原子性、一致性、隔離性、永續性。其中事務的隔離比較重要,事務隔離性處理在資料併發量較大的系統顯得比較重要。

資料庫在事務隔離這塊提供了四種事務隔離級別,分別是:讀取未提交內容(read uncommitted),讀取已提交內容(read committed),可重讀(repeatable read),序列化(serializable)。

不同的資料庫關於事務隔離的預設級別不同,oracle資料庫預設的隔離級別為read committed, mysql的預設隔離之別則為repeatable read;

為什麼不同的資料庫採用了不同的預設隔離級別?因為不同的隔離級別在併發運算元據庫時會產生不同的問題。 也就是由隔離級出現對應的問題:髒讀、不可重複讀及幻讀。

先了解這幾個問題的概念及產生。引用自:

mysql事務隔離詳解

(1) 髒讀:在事務併發處理過程中,某一事務讀取了另乙個事務未提交的資料。如事務a讀取到了事務b修改過的資料,但事務b未進行提交。

時間點事務a

事務b1

select t.money  from t_account t where t.name='scl'

2update t_account t set t.money = t.money+1000 where t.name = 'scl'

3select t.money from t_account t where t.name = 'scl'

4commit

假如 在兩事務a、b 都未執行前,scl賬號有1000元, 在事務開始後,如果事務a第一次讀取到的資料為1000,第二次讀到的資料為2000。那麼這就出現了髒讀。因為在兩個不同事務裡面應該是相互獨立的。不應該讀到其他事務的資料。

(2)  不可重複讀:在事務併發處理過程中,事務a在某時間點1內讀到的資料跟時間點2讀到的資料不一致。跟髒讀的區別是,事務a先進行查詢,然後事務b提交了某一行記錄的修改,事務a再次查詢資料發現兩次讀出來的資料不一致。(事務a讀取了事務b提交的內容,兩次查詢某一行或幾行資料內容不一致)

時間點事務a

事務b1

select t.money  from t_account t where t.name='scl'

2update t_account t set t.money = t.money+1000 where t.name = 'scl'

3commit;

4select t.money from t_account t where t.name = 'scl'

假如 在兩事務a、b 都未執行前,scl賬號有1000元, 在事務開始後,如果事務a第一次讀取到的資料為1000,第二次讀到的資料為2000。那麼這就出現了不可重複讀。因為在      兩個不同事務裡面應該是相互獨立的。a讀到了b提交的事務,導致兩次讀取結果內容不一致。

(3)  幻讀:某事務a進行a表資料查詢,然後事務b在a表內插入了一些新資料並且提交,事務a兩次查詢的資料條數存在差異。 與不可重複讀得區別是資料條數增加了。

時間點事務a

事務b1

select *  from t_account t  

2insert into t_account values ("1000","張三",2000);

insert into t_account values ("1000","李四",3000);

insert into t_account values ("1000","王五",4000);

insert into t_account values ("1000","錢六",6000);

3commit;

4select *  from t_account t  

假如 在兩事務a、b 都未執行前,使用sql:select * from t_account 返回的是3條資料,在兩事務開啟後,事務a第一次讀取到3條資料,在事務b提交後,事務a讀取到了7條資料,那麼久出現了幻讀現象。

既然事務隔離級別不同會導致事務併發產生問題,那麼四個事務隔離級別分別會產生什麼問題?在開發時應選擇什麼哪個隔離級別方式?

隔離級別

髒讀不可重複讀

幻讀讀取未提交內容(read uncommitted)√√

√讀取已提交內容(read committed)x√

√可重讀(repeatable read)xx

√序列化(serializable)xx

x可重讀這個隔離級別有可能會出現幻讀,有可能不出現。取決於資料庫當時的實現。

mysql事務隔離有全域性事務,會話事務之分。可以通過以下指令查詢mysql裡面事務的隔離級別:

1.select @@global.tx_isolation; 

2.select @@session.tx_isolation;

3.select @@tx_isolation;

session 指的是當前連線的事務級別,global則是全域性的隔離級別。應該使用gobal來設定全域性事務隔離級別。並進行相關的測試。

修改事務隔離級別使用指令:set tx_isolation='read-committed';

或者完整的事務隔離更改方法:set global transaction isolation level read committed;

需要注意的是:即使使用了全域性事務隔離級別設定,但開啟的視窗可能有session級別的快取,把查詢視窗關閉再進行一次查詢即可確認事務級別是 否正確修改。(在64位mysql5.5下測試過,無法在已開視窗下正確查詢事務隔離級別)

以上為本人對mysql事務隔離級別的學習總結,如有錯誤,煩請指出糾正。

事務隔離性

事務a 讀取事務b更新的資料,然後事務b回滾,那麼a讀取到的資料就是髒資料 情景展示 1.會話b 可提交讀 set session transaction isolation level read uncommitted begin update account set balance balanc...

事務的隔離性

例如 統計定單系統中事務活動 如下 1.事務t1列印定單表中的記錄 2.t2向定單表插入了新的定單,t2提交 3.事務t1統計定單表中的的記錄總數,t1提交 因為事務t2在t1結束前向定單表中插入了新的記錄,導致事務t1列印的定單記錄數量和t1統計的定單數量不一致.產生併發異常問題的主要原因是併發操...

Mysql 事務隔離性

事務併發所引起的跟讀取資料有關的問題,各用一句話來描述一下 1.髒讀 事務 a 讀取了事務 b 未提交的資料,並在這個基礎上又做了其他操作。讀取未提交 2.不可重複讀 事務 a 讀取了事務 b 已提交的更改資料。讀取新提交update 3.幻讀 事務 a 受到事務 b 已提交的新增資料影響。看不到已...