MySQL的repeatable read
####在 REPEATABLE-READ隔離級別下, session 1
mysql> SELECT @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ |
+-------------------------+
1 row in set (0.00 sec)
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from tb2;
+------+------+
| id | c1 |
+------+------+
| 20 | 0 |
| 30 | 0 |
| 10 | 0 |
+------+------+
3 rows in set (0.00 sec)
####在 REPEATABLE-READ隔離級別下, session 2執行下列操作
mysql> START TRANSACTION;
mysql> insert into tb2 values(40,0);
mysql> commit;
或者
mysql> START TRANSACTION;
mysql> delete from tb2 where id=20;
mysql> commit;
或者
mysql> START TRANSACTION;
mysql> update tb2 set c1=111 where id=10;
mysql> commit;
####在 REPEATABLE-READ隔離級別下, session 1
mysql> select * from tb2;
+------+------+
| id | c1 |
+------+------+
| 20 | 0 |
| 30 | 0 |
| 10 | 0 |
+------+------+
3 rows in set (0.00 sec)
在session 1的同一個transaction中,兩次相同查詢得到的結果一樣,稱之為: repeatable read
==========================================================================
但是在RR隔離級別下,locking read(SELECT with FOR UPDATE or LOCK IN SHARE MODE) 或更新,刪除時是會看到已提交的修改的,包括新插入的行。
####在 REPEATABLE-READ隔離級別下, session 1
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.01 sec)
mysql> select id,c1 from tb2 where id=10;
+------+------+
| id | c1 |
+------+------+
| 10 | 0 |
+------+------+
1 row in set (0.00 sec)
mysql>
####session 2:
mysql> update tb2 set c1=101 where id =10;
####session 1:
mysql> select id,c1 from tb2 where id=10;
+------+------+
| id | c1 |
+------+------+
| 10 | 0 |
+------+------+
1 row in set (0.00 sec)
mysql> select id,c1 from tb2 where id=10 LOCK IN SHARE MODE;
+------+------+
| id | c1 |
+------+------+
| 10 | 101 |
+------+------+
1 row in set (0.00 sec)
mysql> update tb2 set c1=c1+1000 where id=10;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select id,c1 from tb2 where id=10;
+------+------+
| id | c1 |
+------+------+
| 10 | 1101 |
+------+------+
1 row in set (0.00 sec)
mysql> select id,c1 from tb2 where id=10 LOCK IN SHARE MODE;
+------+------+
| id | c1 |
+------+------+
| 10 | 1101 |
+------+------+
1 row in set (0.00 sec)
mysql>
===========================================================================
在RR的隔離級別下,預設採用Next-Key Locks(Record lock和gap lock的結合),它既鎖住記錄本身,也鎖住索引之間的間隙,所以這個gap lock機制預設開啟,並不會產生幻行
在MySQL 5.6.3之前,可以使用innodb_locks_unsafe_for_binlog引數可以禁用gap lock。
innodb_locks_unsafe_for_binlog was deprecated in MySQL 5.6.3. The READ COMMITTED isolation level provides similar functionality.
以下設定成RC隔離級別,模擬幻讀
==========================================================================
####Session 1: 設定隔離級別
mysql> set global transaction isolation level read committed;
mysql> set session transaction isolation level read committed;
mysql> select @@global.transaction_isolation,@@transaction_isolation;
####Session 1: 發起一個事務,檢視資料
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t where id>2 for update;
+------+------+
| id | name |
+------+------+
| 3 | VV |
+------+------+
1 row in set (0.00 sec)
####Session 2: 插入一行資料
mysql> insert into t values(4,'YY');
Query OK, 1 row affected (0.01 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
####Session 1: 再次查詢,出現幻讀
mysql> select * from t where id>2 for update;
+------+------+
| id | name |
+------+------+
| 3 | VV |
| 4 | YY |
+------+------+
2 rows in set (0.00 sec)
========================================================================
gap鎖的出現主要是為了避免幻讀,gap鎖只會阻塞insert操作, 資料庫施加gap lock的條件:
1 事務隔離級別為REPEATABLE-READ,且sql走的索引為非唯一索引
或者
2 事務隔離級別為REPEATABLE-READ,且sql是一個範圍的當前讀操作,這時即使不是非唯一索引也會加gap lock
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/725820/viewspace-2712102/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 如何理解mysql 的事務隔離級別 repeatable readMySql
- read repeatable&read committed 區別MIT
- mysql中read commited與repeatable read兩種隔離級別的測試MySqlMIT
- read committed 和 repeatable read 上鎖的區別MIT
- mysql(InnoDB)事務隔離級別(REPEATABLE READ) 與 鎖,MVCCMySqlMVC
- 【眼見為實】自己動手實踐理解資料庫REPEATABLE READ && Next-Key Lock資料庫
- 【Mysql】FLUSH TABLES WITH READ LOCKMySql
- MySQL之Handler_read_*MySql
- MySQL資料庫事務各隔離級別加鎖情況--Repeatable ReaMySql資料庫
- MySQL 5.6 global read lock 介紹MySql
- 【MySQL】MySQL5.6新特性之Multi-Range ReadMySql
- MYSQL: Handler_read_%引數說明MySql
- mysql關於FLUSH TABLES和FLUSH TABLES WITH READ LOCK的理解MySql
- MySQL5.7 Waiting for global read lockMySqlAI
- MySQL:Innodb Handler_read_*引數解釋MySql
- mysql snapshot read快照讀及current read當前讀與鎖lock之一MySql
- Django Mysql SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTEDDjangoMySqlSessionMIT
- MySQL5.6新特性之Multi-Range ReadMySql
- MySQL 報錯'Variable 'XXX' is a read only variable'MySql
- MySQL 5.5 FLUSH TABLES WITH READ LOCK語句介紹MySql
- read name 和 read 在 Bash 中的區別
- 等待事件db file sequential read、db file scattered read和direct read的區別事件
- MySQL報錯Table 'plugin' is read only [ERROR] Can't open the mysql.plugin table.MySqlPluginError
- Mysql的read_only 只讀屬性說明 (運維筆記)MySql運維筆記
- mysql 5.5引數--innodb_read(write)_io_threadsMySqlthread
- 對Mysql中的read_only 只讀屬性做簡要說明MySql
- direct path read/read temp等待事件事件
- MySQL 中出現報錯提示: ‘Variable ‘XXX‘ is a read only variable‘的解決方法MySql
- READ ME
- MySQL 8.0新特性-並行查詢innodb_parallel_read_threadsMySql並行Parallelthread
- mysql [ERROR] InnoDB: ./ibdata1 can't be opened in read-write modeMySqlError
- Handler_read_*的總結
- mvcc中的read_viewMVCView
- 事務的read only mode
- shell 中read命令的使用
- aix中read命令的用法AI
- mysql啟動時報錯Can't read from messagefile errmsg.sysMySql
- MySQL 8.0 Reference Manual(讀書筆記66節--locking read 與lock)MySql筆記