mysql隔離機制
事務:是一組原子性的SQL查詢語句,也可以被看做一個工作單元。
事務具有的四個特性:原子性(atomicity)、一致性(consistency)、隔離性(isolation)、永續性(durability)
1.關聯式資料庫標準中的4個事務隔離級別
#未提交讀(read uncommitted): 允許髒讀,也就是可能讀取到其他會話中未提交事務修改的資料
#提交讀(read committed): 只能讀取到已經提交的資料。oracle等多數資料庫預設都是該級別
#可重複讀(repeated read): 可重複讀。在同一個事務內的查詢都是事務開始時刻一致的,innodb的預設級別。
在SQL標準中,該隔離級別消除了不可重複讀,但是還存在幻象讀
#序列讀(serializable): 完全序列化的讀,每次讀都需要獲得表級共享鎖,讀寫相互都會阻塞。
2.事務併發導致的幾個問題
#髒讀(Drity Read):某個事務已更新一份資料,另一個事務在此時讀取了同一份資料,由於某些原因,前一個RollBack了操作,則後一個事務所讀取的資料就會是不正確的。
#不可重複讀(Non-repeatable read):在一個事務的兩次查詢之中資料不一致,這可能是兩次查詢過程中間插入了一個事務更新的原有的資料。
#幻讀(Phantom Read):在一個事務的兩次查詢中資料筆數不一致,例如有一個事務查詢了幾列(Row)資料,而另一個事務卻在此時插入了新的幾列資料,先前的事務在接下來的查詢中,就會發現有幾列資料是它先前所沒有的。
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
|
|
|
檢視InnoDB系統級別的事務隔離級別:
| @@global.tx_isolation |
+-----------------------+
| REPEATABLE-READ |
+-----------------------+
1 row in set (0.00 sec)
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)
mysql> set global transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)
測試:
1. 建測試表,並加入一條資料
CREATE TABLE `isotest` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`score` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
mysql> insert into isotest (name,score) values('wjlcn',80);
2. 建立兩個連線,假定 A、B
* 測試隔離級為 read uncommitted 和 read committed
將A、B 分別設定隔離級為 read uncommitted
mysql> set autocommit=off;
mysql> set session transaction isolation level read uncommitted;
mysql> select @@tx_isolation;
+------------------+
| @@tx_isolation |
+------------------+
| READ-UNCOMMITTED |
+------------------+
A:
mysql> update isotest set score=90 where name='wjlcn';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from isotest;
+----+-------+-------+
| id | name | score |
+----+-------+-------+
| 1 | wjlcn | 90 |
+----+-------+-------+
1 row in set (0.00 sec)
B:
mysql> set session transaction isolation level read uncommitted; -----髒讀
Query OK, 0 rows affected (0.00 sec)
mysql> select * from isotest;
+----+-------+-------+
| id | name | score |
+----+-------+-------+
| 1 | wjlcn | 90 |
+----+-------+-------+
1 row in set (0.00 sec)
mysql> set session transaction isolation level read committed; ----不可髒讀
Query OK, 0 rows affected (0.00 sec)
mysql> select * from isotest;
+----+-------+-------+
| id | name | score |
+----+-------+-------+
| 1 | wjlcn | 80 |
+----+-------+-------+
1 row in set (0.00 sec)
注:在 read uncommitted 隔離級,B上可以髒讀,而在read committed上卻不可以。
A:
mysql> commit;
Query OK, 0 rows affected (0.01 sec)
B:
mysql> select * from isotest; ----不可重複讀,oracle常用的機制
+----+-------+-------+,
| id | name | score |
+----+-------+-------+
| 1 | wjlcn | 90 |
+----+-------+-------+
1 row in set (0.00 sec)
注:當A執行commit後,在read committed上讀到了修改後的資料,驗證了不可重複讀。
* 測試隔離級為 repeatable read
將A、B 隔離級設定為:repeatable read
mysql> set session transaction isolation level repeatable read;
測試不可重複讀可能性
A:
mysql> update isotest set score=100 where name='wjlcn';
B:
mysql> select * from isotest;
+----+-------+-------+
| id | name | score |
+----+-------+-------+
| 1 | wjlcn | 90 |
+----+-------+-------+
1 row in set (0.00 sec)
A:
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
B:
mysql> select * from isotest;
+----+-------+-------+
| id | name | score |
+----+-------+-------+
| 1 | wjlcn | 90 |
+----+-------+-------+
1 row in set (0.01 sec)
注:A事務已經commit,B事務中資料仍舊沒變,驗證了可重複讀。
A事務已經commit,而B事務查的資料沒變,在B事務沒有提交前,對同一行資料進行update又會怎樣?(另外已經驗證,會在A事務commit後再進行update)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from isotest;
+----+-------+-------+
| id | name | score |
+----+-------+-------+
| 1 | wjlcn | 100 |
+----+-------+-------+
1 row in set (0.00 sec)
注:只有將B事務commit,重新開始新的事務時,才可以查到更改後的資料。
測試幻讀可能性
A:
mysql> insert into isotest (name,score) values('kaka',80);
Query OK, 1 row affected (0.00 sec)
mysql> select * from isotest;
+----+-------+-------+
| id | name | score |
+----+-------+-------+
| 1 | wjlcn | 100 |
| 2 | kaka | 80 |
+----+-------+-------+
2 rows in set (0.00 sec)
B:
mysql> select * from isotest;
+----+-------+-------+
| id | name | score |
+----+-------+-------+
| 1 | wjlcn | 100 |
+----+-------+-------+
1 row in set (0.00 sec)
A:
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
B:
mysql> select * from isotest;
+----+-------+-------+
| id | name | score |
+----+-------+-------+
| 1 | wjlcn | 100 |
+----+-------+-------+
1 row in set (0.00 sec)
注:此時用
//mysql> select * from isotest lock in share mode;
//mysql> select * from isotest for update;
//可以查到2條記錄,InnoDB提供了這樣的機制,在預設的可重複讀的隔離級別裡,可以使用加鎖讀去查詢最新的資料。
mysql> update isotest set score=180;
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
mysql> select * from isotest;
+----+-------+-------+
| id | name | score |
+----+-------+-------+
| 1 | wjlcn | 180 |
| 2 | kaka | 180 |
+----+-------+-------+
2 rows in set (0.00 sec)
怎麼啦?咋多出一行? 幻讀來了……
但innodb 在repeatable read可以避免幻讀又是怎麼回事?
MySQL InnoDB的可重複讀並不保證避免幻讀,需要應用使用加鎖next-key locks讀來保證。
* 測試隔離級為 serializable
A:
mysql> set session transaction isolation level serializable;
mysql> update isotest set score=300 where id=4;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
B:
mysql> set session transaction isolation level serializable;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from isotest;
此時,B事務會被阻塞,因為A事務要個更新id=4 這一行,因此給這行加上了排它鎖,B事務再將給 其加上共享鎖將會失敗。使用A事務commit之後,B事務才會往下執行。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29096438/viewspace-1420456/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- mysql 事務,鎖,隔離機制MySql
- Mysql事務隔離級別與鎖機制MySql
- MySQL學習系列之InnoDB下事務隔離機制MySql
- 詳解Mysql事務隔離級別與鎖機制MySql
- qiankun 的 CSS 沙箱隔離機制CSS
- qiankun 的 JS 沙箱隔離機制JS
- 容器的工作原理和隔離機制
- PostgreSQL 併發控制機制(4):RR隔離級別,MySQL vs PostgreSQLMySql
- 一文讀懂MySQL的事務隔離級別及MVCC機制MySqlMVC
- 深入理解Mysql事務隔離級別與鎖機制問題RLOGMySql
- MySQL事務隔離MySql
- MySQL 事務隔離MySql
- PostgreSQL 併發控制機制(1):隔離級別SQL
- 微服務熔斷隔離機制及注意事項微服務
- MySQL的隔離級別MySql
- dart系列之:dart優秀的祕訣-隔離機制Dart
- MySQL事務隔離級別MySql
- 4.MySQL--事務隔離MySql
- MySQL 事務隔離級別MySql
- [Mysql]事務/隔離級別MySql
- MySQL學習之事務隔離MySql
- MySQL事務的隔離級別MySql
- MySQL 入門(3):事務隔離MySql
- MySQL 的隔離級別 自理解MySql
- MySQL是如何實現事物隔離?MySql
- 理解MySQL事務隔離級別MySql
- MySQL的事務隔離級別MySql
- SAP Hybris和Netweaver的租戶隔離(Tenant isolation)機制設計NaN
- 淺析MySQL InnoDB的隔離級別MySql
- Mysql資料庫的隔離級別MySql資料庫
- MySQL事務隔離級別和MVCCMySqlMVC
- 深入淺出MYSQL的事務隔離MySql
- 理解mysql的事務隔離級別MySql
- 啥是 MySQL 事務隔離級別?MySql
- mysql如何修改事務隔離級別MySql
- MySQL之事務隔離級別和MVCCMySqlMVC
- mysql事務隔離級別和鎖MySql
- Mysql鎖與事務隔離級別MySql
- Mysql 四種事務隔離級別MySql