Mysql Innodb transaction isolation level understanding

Keywords: MySQL Session snapshot

Mysql has four transaction isolation levels, as follows:
1.Read Uncommitted allows you to read dirty data that has been changed by other transactions but has not been submitted. It also causes unrepeatable and hallucination problems.
2.Read Committed can avoid reading dirty data, and still cause unrepeatable and hallucination problems.
3. The default isolation level of REPEATABLE-READ mysql results in hallucination. However, the level of mysql uses MVCC consistent reading and does not produce hallucination.
4.Serializable's highest isolation level will avoid the above problems.

The isolation level of the current system can be viewed in the following ways

mysql> select @@global.tx_isolation,@@tx_isolation;
+-----------------------+-----------------+
| @@global.tx_isolation | @@tx_isolation  |
+-----------------------+-----------------+
| REPEATABLE-READ       | REPEATABLE-READ |
+-----------------------+-----------------+
1 row in set (0.00 sec)

No READ-UNCOMMITTED dirty reading and non-repeatable reading examples were submitted:

#session A
mysql> set session transaction isolation level read uncommitted;   #Set isolation level to uncommitted read
Query OK, 0 rows affected (0.00 sec)

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

mysql> select * from inno_tbl where id=2;
+----+------+
| id | name |
+----+------+
|  2 | John |
+----+------+
1 row in set (0.00 sec)
#session B
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)

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

mysql> update inno_tbl set name='Jack Ma' where id=2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
#session A
mysql> select * from inno_tbl where id=2;
+----+---------+
| id | name    |
+----+---------+
|  2 | Jack Ma |
+----+---------+
1 row in set (0.00 sec)

At this time session A reads the modified but uncommitted data of session B. If session B rolls back at this time, the data read by A will be invalid, which is "dirty data". Because the data read by A for the first time is different from the data read by the second time, this is "non-repeatable reading". Similarly, or inserting new data into B, the new data rows read in this transaction will also be read in A. This is illusion reading.
In the same process, if the isolation level of A is changed to read committed, dirty reading will not occur, but "unrepeatable reading" and "hallucination" will also occur.

Under the default isolation level REPEATABLE-READ:

#session A
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from inno_tbl where id=2;
+----+--------------+
| id | name         |
+----+--------------+
|  2 | John         |
+----+--------------+
1 row in set (0.00 sec)
#session B
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> update inno_tbl set name='Lucy' where id=2; 
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
mysql> commit;
Query OK, 0 rows affected (0.03 sec)
#session A
mysql> select * from inno_tbl where id=2;
+----+--------------+
| id | name         |
+----+--------------+
|  2 | John         |
+----+--------------+
1 row in set (0.00 sec)
#Note that there is no "non-repeatable read" problem, but if a shared lock is added to the query:
mysql> select * from inno_tbl1 where id=2 lock in share mode;
+----+---------+
| id | name    |
+----+---------+
|  2 | Lucy    |
+----+---------+
1 row in set (0.00 sec)

Description: Transactions in Session A read the name field in inno_tbl table with id 2 as John, and if the transaction in Session B changes the name of id 2 in inno_tbl to Lucy and commits, if the transaction in Session A reads the row data again, it will find that if the transaction in Session A directly uses select mode to query, the read data will still be old, and with shared lock, the real data will be read out. Why? In nnodb engine, mysql add-delete query statements can be divided into two kinds: snapshot reading, one is current reading, only ordinary query statements are snapshot reading, while the remaining add-delete query statements with lock in share mode shared lock or add for update exclusive lock are current reading; at that time, the latest data was read, while snapshot reading is not necessarily the latest data. This can be deduced: When the condition is name=John to update or delete in session A, it will not update or delete successfully, as follows:

mysql> update inno_tbl set name='Zhang San' where name='John';
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0
mysql> delete from inno_tbl where name='John';
Query OK, 0 rows affected (0.00 sec)

If the isolation level is changed to Read Commited, the query statement in A session can query the latest changed submissions in B session without adding lock in share mode or for update. This situation is called non-repeatable reading. As I write here, I have a little question, is non-repeatable reading and hallucination contradictory?

Posted by mrcodex on Tue, 25 Jun 2019 14:01:43 -0700