MySQL資料庫事務的隔離級別介紹

2021-05-26 09:38:37 字數 4128 閱讀 6263

在大學學習資料庫的時候就接觸到了事務,但在現在的工作中也沒有使用過,因為平台不支援,在需要保證資料一致性的時候就要自己做,比如有兩條delete語句,當第一條執行成功第二條失敗的時候,就要把第一條刪除的記錄再新增上,非常麻煩。也致使自己對事務沒有真正理解和掌握。

使用事務是保證資料的正確性,n條sql語句組成乙個事務,這n條語句都成功則成功,若有一條失敗則失敗,需要回滾到執行前的狀態。

事務的acdi特性:

a:automicity,原子性

c:consistency,一致性

i:isolation,隔離性

d:durability,持續性

mysql資料庫的不同儲存引擎對事務的支援不同,myisam儲存引擎不支援事務,innodb儲存引擎支援事務,比較常用

一、事務隔離級別

ansi/iso sql標準定義了4中事務隔離級別:未提交讀(read uncommitted),提交讀(read committed),重複讀(repeatable read),序列讀(serializable)。

對於不同的事務,採用不同的隔離級別分別有不同的結果。不同的隔離級別有不同的現象。主要有下面3種現在:

1、髒讀(dirty read):乙個事務可以讀取另乙個尚未提交事務的修改資料。

2、非重複讀(nonrepeatable read):在同乙個事務中,同乙個查詢在t1時間讀取某一行,在t2時間重新讀取這一行時候,這一行的資料已經發生修改,可能被更新了(update),也可能被刪除了(delete)。

3、幻像讀(phantom read):在同一事務中,同一查詢多次進行時候,由於其他插入操作(insert)的事務提交,導致每次返回不同的結果集。

不同的隔離級別有不同的現象,並有不同的鎖定/併發機制,隔離級別越高,資料庫的併發性就越差,4種事務隔離級別分別表現的現象如下表:

二、資料庫中的預設事務隔離級別

在oracle中預設的事務隔離級別是提交讀(read committed)。

對於mysql的innodb的預設事務隔離級別是重複讀(repeatable read。可以通過下面的命令檢視:

mysql> select @@global.tx_isolation, @@tx_isolation;

| @@global.tx_isolation | @@tx_isolation  |

| repeatable-read | repeatable-read |

1 row in set (0.00 sec)

下面進行一下測試:

timesession 1session 2

t1set autocommit=0;

set autocommit=0;

t2mysql> select * from tmp_test; +——+———+

| id   | version |

+——+———+

|    1 |       1 |

+——+———+

1 row in set (0.00 sec)

t3mysql> update tmp_test set version=2 where id=1; query ok, 1 row affected (0.02 sec)

rows matched: 1  changed: 1  warnings: 0

mysql> select * from tmp_test;

+——+———+

| id   | version |

+——+———+

|    1 |       2 |

+——+———+

1 row in set (0.00 sec)

t4mysql> select * from tmp_test; +——+———+

| id   | version |

+——+———+

|    1 |       1 |

+——+———+

1 row in set (0.00 sec)

【說明】

session 2未提交,看到資料不變,無髒讀。t5

commit;

t6mysql> select * from tmp_test; +——+———+

| id   | version |

+——+———+

|    1 |      1 |

+——+———+

1 row in set (0.00 sec)

【說明】

session 2已經提交,還是看到資料不變,即可以重複讀。t7

commit;

t8mysql> select * from tmp_test; +——+———+

| id   | version |

+——+———+

|    1 |       2 |

+——+———+

1 row in set (0.00 sec)

【說明】

提交事務,看到最新資料。t9

mysql> insert into tmp_test values(2,1); query ok, 1 row affected (0.00 sec)

mysql> select * from tmp_test;

+——+———+

| id   | version |

+——+———+

|    1 |       2 |

|    2 |       1 |

+——+———+

2 rows in set (0.00 sec)

mysql> commit;

query ok, 0 rows affected (0.00 sec)

t10mysql> select * from tmp_test; +——+———+

| id   | version |

+——+———+

|    1 |       2 |

+——+———+

1 row in set (0.00 sec)

【說明】

session 2的insert事務已經提交,看到的資料和t8的時候一樣,即未發生幻象讀。

t11mysql> commit; query ok, 0 rows affected (0.00 sec)

mysql> select * from tmp_test;

+——+———+

| id   | version |

+——+———+

|    1 |       2 |

|    2 |       1 |

+——+———+

2 rows in set (0.00 sec)

【說明】

事務提交,看到最新資料。

上面的結果可以看到innodb的重複讀(repeatable read)不允許髒讀,不允許非重複讀(即可以重複讀,innodb使用多版本一致性讀來實現)和不允許幻象讀(這點和ansi/iso sql標準定義的有所區別)。

另外,同樣的測試:

1、當session 2進行truncate表的時候,這個時候session 1再次查詢就看不到資料。

2、當session 2進行alter表的時候,這個時候session 1再次查詢就看不到資料。

mysql官方文件中的多版本一致性讀中說明了原因:consistent read does not work over certain ddl statements

mysql資料庫事務隔離級別

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

MYSQL 資料庫 事務 隔離級別

定義 在資料庫 中,為了有效保證併發讀取資料的正確性,提出的事務隔離級別,由低到高依次為 1 read uncommitted 未授權讀取 讀未提交 2 read committed 授權讀取 讀提交 3 repeatable read 可重複讀取 4 serializable 序列化 這四個事務隔...

MySQL資料庫事務隔離級別

一 資料庫事務併發訪問引發的問題 二 mysql資料庫的四種事務隔離級別 隔離級別 名稱髒讀 不可重複讀 幻讀資料庫預設級別 read uncommitted 讀未提交是是 是read committed 讀已提交否是 是oracle sql server repeatable read 可重複讀否...