MYSQL資料庫事務4種隔離級別及7種傳播行為

2021-08-30 17:47:41 字數 3971 閱讀 9853

原子性:事務的不可分割,組成事務的各個邏輯單元不可分割。

一致性:事務執行的前後,資料完整性保持一致。

隔離性:事務執行不應該受到其他事務的干擾。

永續性:事務一旦結束,資料就持久化到資料庫中。

檢視:select @@tx_isolation  設定:set tx_isolation='***'

如果不考慮隔離性,引發一些安全問題

隔離性:乙個事務的執行,不應該受到其他事務的干擾。

髒讀:乙個事務讀到了另乙個事務未提交的資料,導致查詢結果不一致

不可重複讀:乙個事務讀到了另乙個事務已經提交的update的資料,導致多次查詢結果不一致。

虛讀/幻讀:乙個事務讀到了另乙個事務已經提交的insert的資料,導致多次查詢結果不一致。

read uncommitted (讀取未提交內容)   :髒讀,不可重複讀,虛讀都有可能發生

read committed (讀取提交內容)   :避免髒讀。但是不可重複讀和虛讀是有可能發生

repeatable read (可重讀)   :避免髒讀和不可重複讀,但是虛讀有可能發生。

serializable(可序列化)        :避免髒讀,不可重複讀,虛讀。

read uncommitted (讀取未提交內容)  :

事務a:開啟事務並執行 select * from testtest, 但並不提交事務

set tx_isolation='read-uncommitted';

start transaction;

select * from testtest;

結果顯示:

事務b:開始事務並執行  update testtest set age = 200 where name = 'zhangsan'; 但並不提交事務

start transaction;

update testtest set age = 200 where name = 'zhangsan';

事務a:再次執行  select * from testtest

在事務b未提交的情況下,仍然讀到了修改的200,出現了髒讀!

read committed (讀取提交內容)

事務a:開啟事務並執行 select * from testtest, 但並不提交事務

事務b:開始事務並執行  update testtest set age = 200 where name = 'zhangsan'; 但並不提交事務

start transaction;

update testtest set age = 200 where name = 'zhangsan';

事務a:再次執行  select * from testtest

在事務b未提交的情況下,沒有讀到修改的200,避免了髒讀!

事務b:提交事務。

事務a:再次執行  select * from testtest

在事務b提交的情況下,讀到了修改的200,出現了不可重複讀!(同乙個事務中多次讀取結果不一致)

repeatable read (可重讀)  mysql預設

事務a:開啟事務並執行 select * from testtest, 但並不提交事務

事務b:開始事務並執行  update testtest set age = 200 where name = 'zhangsan'; 但並不提交事務

start transaction;

update testtest set age = 200 where name = 'zhangsan';

事務a:再次執行  select * from testtest

在事務b未提交的情況下,沒有讀到修改的200,避免了髒讀!   

事務b:提交事務。

事務a:再次執行  select * from testtest

在事務b提交的情況下,沒有讀到修改的200,避免了不可重複讀!

再次 開啟事務b,並新增一條記錄,並提交事務

start transaction;

insert into testtest(name,age) values ('wangwu','100');

commit;

事務a:再次執行  select * from testtest

並沒有讀到新增的記錄

事務a:插入剛才事務b新增的記錄

insert into testtest(name,age) values ('wangwu','100');
發現插不進去,因為事務b已經新增並提交事務了(我們name欄位做了唯一索引),出現了幻讀!(查詢的時候沒有,但插入的時候確實存在,跟出現幻覺一樣)。

serializable(可序列化)

事務a:開啟事務並執行 select * from testtest, 但並不提交事務

start transaction;

select * from testtest;

事務b:開始事務並執行  update testtest set age = 200 where name = 'zhangsan'

發現事務b停在那裡了,沒有任何執行,直到事務a提交事務。簡言之,它是在每個讀的資料行上加上共享鎖。在這個級別,可能導致大量的超時現象和鎖競爭。

1、propagation_required:如果當前沒有事務,就建立乙個新事務,如果當前存在事務,就加入該事務,該設定是最常用的設定。

2、propagation_nested:如果當前存在事務,則在巢狀事務內執行。如果當前沒有事務,則執行與propagation_required類似的操作

3、propagation_supports:支援當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就以非事務執行。『

4、propagation_mandatory:支援當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就丟擲異常。

5、propagation_requires_new:支援當前事務,建立新事務,無論當前存不存在事務,都建立新事務。

6、propagation_not_supported:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。

7、propagation_never:以非事務方式執行,如果當前存在事務,則丟擲異常。

擴充套件:

MySQL資料庫 innodb事務的隔離級別

1.髒讀 乙個事務,讀到另外一條未提交事務的資料 read uncommitted出現 2.不可重複讀 乙個事務多次讀取到的資料不一致 read committed出現 3.幻讀 事務ab,事務a插入一條資料,事務b修改所有的資料,發現修改的行數比之前多,好像產生了幻覺一樣 用一張表account來...

MySQL資料庫事務隔離

mysql資料庫事務隔離級別主要有四種 1,serializable 序列化,乙個事務乙個事務的執行 2,repeatable read 可重複讀,無論其他事務是否修改並提交了資料,在這個事務中看到的資料值始終不受其他事務影響 3,read committed 讀取已提交,其他事務提交了對資料的修改...

mysql資料庫事務隔離級別

1修改事務隔離級別 全域性修改 修改mysql.ini配置檔案 mysqlid transaction isolation repeatble read 對當前session修改 登入mysql客戶端後,執行命令set session transaction isolation level read...