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。
待續。。。