由幻讀引起的嘗試。。

set_autocommit = onmysql

隔離界別 RRsql

mysql-server-version: 5.7.26bash

示例1:基本的幻讀產生場景併發

事務A:
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from student;
+----+------+
| id | name |
+----+------+
| 23 | A    |
| 24 | B    |
| 25 | C    |
+----+------+
3 rows in set (0.00 sec)

事務B:
mysql> insert into student (name) values ('D');
Query OK, 1 row affected (0.01 sec)

事務A:
mysql> select * from student;
+----+------+
| id | name |
+----+------+
| 23 | A    |
| 24 | B    |
| 25 | C    |
+----+------+
3 rows in set (0.00 sec)
複製代碼

在隔離界別爲RR的狀況下,並未出現幻讀。因爲多版本併發控制(Multi-Version Concurrency Control, MVCC)的存在,在select執行的時候產生了一個快照讀,因此事務A中的後續操做,並不會受事務B的影響。post

示例2:若是製造幻讀?ui

在示例1的基礎上繼續執行
事務B:
mysql> insert into student (name) values ('F');
Query OK, 1 row affected (0.11 sec)

mysql> select * from student;
+----+------+
| id | name |
+----+------+
| 23 | A    |
| 24 | B    |
| 25 | B    |
| 26 | D    |
| 27 | E    |
| 28 | F    |
+----+------+
6 rows in set (0.00 sec)

事務A:
# 並無新增的28-F
mysql> select * from student;
+----+------+
| id | name |
+----+------+
| 23 | A    |
| 24 | B    |
| 25 | B    |
| 26 | D    |
| 27 | E    |
+----+------+
5 rows in set (0.00 sec)

# 若是執行範圍更新
mysql> update student set name = 'G' where id > 25;
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3  Changed: 3  Warnings: 0

# 會發現事務B中新增的28-F,變成了28-G, 出現了幻讀
mysql> select * from student;
+----+------+
| id | name |
+----+------+
| 23 | A    |
| 24 | B    |
| 25 | B    |
| 26 | G    |
| 27 | G    |
| 28 | G    |
+----+------+
6 rows in set (0.00 sec)
複製代碼

若是事務A中發生了範圍更新,則會出現幻讀,事務B中新增的數據,出如今了事務A中;若是僅僅只是修改一條數據(update student set name = 'G' where id = 25),卻不會出現這個狀況,具體緣由尚不清楚。。。感受多是範圍更新觸發了當前讀,select的時候又從新生成了新的快照讀(待解決)。spa

示例3:間隙鎖code

繼續沿用示例2,
事務B:
# 阻塞
mysql> insert into student (name) values ('H');
^C^C -- query aborted
ERROR 1317 (70100): Query execution was interrupted

# 可是插入id<25的值會成功
mysql> insert into student (id, name) values (22, 'H');
Query OK, 1 row affected (0.01 sec)

複製代碼

因爲示例2中執行了範圍更新,id>25的name更新爲G,這時會產生間隙鎖,若是其餘事務再插入id>25的數據會阻塞,可是插入id<25的值會成功。orm

示例 4:開啓事務的時機server

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM information_schema.INNODB_TRX;
Empty set (0.00 sec)

mysql> select * from student;
+----+------+
| id | name |
+----+------+
| 22 | H    |
| 23 | A    |
| 24 | B    |
| 25 | B    |
| 26 | G    |
| 27 | G    |
| 28 | G    |
+----+------+
7 rows in set (0.00 sec)

mysql> SELECT * FROM information_schema.INNODB_TRX;
+-----------------+-----------+---------------------+-----------------------+------------------+------------+---------------------+-----------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+------------------+----------------------------+
| trx_id          | trx_state | trx_started         | trx_requested_lock_id | trx_wait_started | trx_weight | trx_mysql_thread_id | trx_query | trx_operation_state | trx_tables_in_use | trx_tables_locked | trx_lock_structs | trx_lock_memory_bytes | trx_rows_locked | trx_rows_modified | trx_concurrency_tickets | trx_isolation_level | trx_unique_checks | trx_foreign_key_checks | trx_last_foreign_key_error | trx_adaptive_hash_latched | trx_adaptive_hash_timeout | trx_is_read_only | trx_autocommit_non_locking |
+-----------------+-----------+---------------------+-----------------------+------------------+------------+---------------------+-----------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+------------------+----------------------------+
| 421518642805496 | RUNNING   | 2019-09-16 18:21:39 | NULL                  | NULL             |          0 |                  15 | NULL      | NULL                |                 0 |                 0 |                0 |                  1136 |               0 |                 0 |                       0 | REPEATABLE READ     |                 1 |                      1 | NULL                       |                         0 |                         0 |                0 |                          0 |
+-----------------+-----------+---------------------+-----------------------+------------------+------------+---------------------+-----------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+------------------+----------------------------+
1 row in set (0.00 sec)

mysql> update student set name = 'I' where id = 28;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM information_schema.INNODB_TRX;
+--------+-----------+---------------------+-----------------------+------------------+------------+---------------------+-----------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+------------------+----------------------------+
| trx_id | trx_state | trx_started         | trx_requested_lock_id | trx_wait_started | trx_weight | trx_mysql_thread_id | trx_query | trx_operation_state | trx_tables_in_use | trx_tables_locked | trx_lock_structs | trx_lock_memory_bytes | trx_rows_locked | trx_rows_modified | trx_concurrency_tickets | trx_isolation_level | trx_unique_checks | trx_foreign_key_checks | trx_last_foreign_key_error | trx_adaptive_hash_latched | trx_adaptive_hash_timeout | trx_is_read_only | trx_autocommit_non_locking |
+--------+-----------+---------------------+-----------------------+------------------+------------+---------------------+-----------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+------------------+----------------------------+
| 13241  | RUNNING   | 2019-09-16 18:21:39 | NULL                  | NULL             |          3 |                  15 | NULL      | NULL                |                 0 |                 1 |                2 |                  1136 |               1 |                 1 |                       0 | REPEATABLE READ     |                 1 |                      1 | NULL                       |                         0 |                         0 |                0 |                          0 |
+--------+-----------+---------------------+-----------------------+------------------+------------+---------------------+-----------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+---------------------------+---------------------------+------------------+----------------------------+
1 row in set (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT * FROM information_schema.INNODB_TRX;
Empty set (0.00 sec)

複製代碼

trx_id:每次對某條聚簇索引記錄進行改動時,都會把對應的事務id賦值給trx_id隱藏列

輸入begin後,事務並無開啓;select查詢後,會查到一條數據,trx_id = 421518642805496(嘗試了多個事務,每次select的trx_id都同樣),當真正執行update, create, delete的時候,會分配一個遞增的trx_id。

待續。。。

參考文章: juejin.im/post/5c9040… juejin.im/post/5c9b1b…

相關文章
相關標籤/搜索