MySQL事務和事務的四種隔離級別 for INNODB

什麼是事務

一組原子性的SQL語句,可以提交或回滾的原子工作單元 。當事務對數據庫進行多次更改時,要麼在提交事務後所有更改成功,要麼在回滾事務時撤消所有更改。

事務特性

ACID特性

  • A: atomicity(原子性):整個事務中的所有操作要麼全部成功,要麼全部失敗後回滾;
  • C: consistency(一致性):整個數據庫總是從一個一致性狀態轉換爲另一個一致性狀態;
  • I: isolation(隔離性):一個事務所做的的操作在提交之前,是不被其它事務所見的;
  • D: durability(持久性):事務一旦提交,其所做的修改會永久保存於數據庫中。

事務生命週期

MySQL事務和事務的四種隔離級別 for INNODB

事務管理

顯式啓動事務:

BEGIN
BEGIN WORK
START TRANSACTION

結束事務:

# 提交
COMMIT
# 回滾
ROLLBACK
注:只有事務型的存儲引擎的DML語句才能支持此類操作

自動提交:

默認爲1,爲0時設爲非自動提交
> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set (0.00 sec)

set autocommit={1|0}
注:建議顯式請求和提交事務,而不要使用“自動提交”功能。

事務支持保存點:

SAVEPOINT identifier
ROLLBACK [WORK] TO [SAVEPOINT] identifier
RELEASE SAVEPOINT identifier

查看事務:

# 查看當前的事務
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
#查看當前鎖定的事務
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
#查看當前等鎖的事務
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;

事務隔離級別

MySQL事務支持四種隔離級別,從上至下更加嚴格

事務隔離級別 說明 髒讀可能性 不可重複讀可能性 幻讀可能性 加讀鎖
READ UNCOMMITTED 可讀取到未提交數據,產生髒讀 Yes Yes Yes No
READ COMMITTED 可讀取到提交數據,但未提交數據不可讀,產生不可重複讀,即可讀取到多個提交數據,導致每次讀取的數據不一致 No Yes Yes No
REPEATABLE READ 可重複讀,多次讀取數據都一致,產生幻讀,即讀取過程中,即使有其它提交的事務修改數據,仍只能讀取到未修改前的舊數據。此爲MySQL默認設置 Yes Yes Yes No
SERIALIZABLE 可串行化,未提交的讀事務阻塞修改事務(加讀鎖,但不阻塞讀事務),或者未提交的修改事務阻塞讀事務(加寫鎖,其它事務的讀,寫都不可以執行)。會導致併發性能差 No No No Yes

MVCC和事務的隔離級別

MVCC(多版本併發控制機制)只在REPEATABLE READ和READ COMMITTED兩個隔離級別下工作。其他兩個隔離級別都和MVCC不兼容,因爲READ UNCOMMITTED總是讀取最新的數據行,而不是符合當前事務版本的數據行。而SERIALIZABLE則會對所有讀取的行都加鎖

如何指定事務隔離級別

參考:https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_tx_isolation

1.系統變量tx_isolation指定,默認爲REPEATABLE-READ,有效範圍:Global, Session
# 語法:
set tx_isolatioin='value';
# 有效值
READ-UNCOMMITTED
READ-COMMITTED
REPEATABLE-READ
SERIALIZABLE
2.服務器選項中指定
在/etc/my.cnf文件的[mysqld]塊中使用transaction-isolation選項設置
[mysqld]
transaction-isolation = value

事務隔離級別驗證

背景:通過兩個終端顯示啓動兩個事務來驗證,用作驗證的user表的表內容和表結構如下

mysql> desc user;
+-------+------------------+------+-----+---------+----------------+
| Field | Type             | Null | Key | Default | Extra          |
+-------+------------------+------+-----+---------+----------------+
| id    | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name  | varchar(30)      | NO   |     | NULL    |                |
+-------+------------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> select * from user;
+----+-------+
| id | name  |
+----+-------+
|  2 | root  |
|  3 | admin |
+----+-------+
2 rows in set (0.00 sec)

1.READ UNCOMMITTED級別

MySQL事務和事務的四種隔離級別 for INNODB

2.READ COMMITTED級別

MySQL事務和事務的四種隔離級別 for INNODB

3.REPEATABLE READ級別

MySQL事務和事務的四種隔離級別 for INNODB

4.SERIALIZABLE級別

未提交的讀事務阻塞修改事務(加讀鎖,但不阻塞讀事務)

MySQL事務和事務的四種隔離級別 for INNODB

未提交的修改事務阻塞讀事務(加寫鎖,其它事務的讀、寫都不可以執行)

MySQL事務和事務的四種隔離級別 for INNODB

注:此種事務隔離級別會導致併發性能差。

附加案例:如果一個事務產生了寫鎖,然後一直未結束事務,這樣會導致其它事務的讀、寫都不可以執行,對於這種情況,可以找到未結束並且導致阻塞的事務,手動將其kill。

拿上面未提交的修改事務阻塞讀事務的案例來驗證

MySQL事務和事務的四種隔離級別 for INNODB

打開第三個會話執行以下操作

MySQL事務和事務的四種隔離級別 for INNODB
MySQL事務和事務的四種隔離級別 for INNODB

死鎖

MySQL事務和事務的四種隔離級別 for INNODB

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章