The MySQL default isolation level REPEATABLE-READ does not solve the phantom read problem

Scanning the pulse, I found a post discussing phantom reading:

https://maimai.cn/web/gossip_detail?src=app&webid=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlZ2lkIjoiN2JmMjA4ZDZjNzU0MTFlYWExOTk4MDE4NDRlNTAxOTAiLCJ1IjoyMjM0MjgzMTksImlkIjoyNjc0NDU3OH0.yvtEe5Z1vjtmPE5dBwXVqD-pMWBE2--jDQuRARcWArI


Let’s do an experiment to demonstrate that the MySQL default isolation level REPEATABLE-READ does not solve the problem of phantom reading.


Phantom reading demo 

MySQL default isolation level REPEATABLE-READ (repeatable read)

Conversation one

Conversation two

MySQL [test]> select * from t1;

+------+

| id   |

+------+

|    1 |

|    2 |

|    3 |

|    4 |

+------+

4 rows in set (0.000 sec)

MySQL [test]> select * from t1;

+------+

| id   |

+------+

|    1 |

|    2 |

|    3 |

|    4 |

+------+

4 rows in set (0.000 sec)

MySQL [test]> begin;

Query OK, 0 rows affected (0.000 sec)

 

Note: Open transaction one

MySQL [test]> begin;

Query OK, 0 rows affected (0.000 sec)

 

Note: open transaction two

MySQL [test]> insert into t1 values(5);

Query OK, 1 row affected (0.000 sec)

 

MySQL [test]> select * from t1;

+------+

| id   |

+------+

|    1 |

|    2 |

|    3 |

|    4 |

|    5 |

+------+

5 rows in set (0.000 sec)

 

Note: Insert a piece of data 5

MySQL [test]> select * from t1;

+------+

| id   |

+------+

|    1 |

|    2 |

|    3 |

|    4 |

+------+

4 rows in set (0.000 sec)

 

Note: Since the first session is not committed, the result of the change cannot be seen in the second transaction

MySQL [test]> commit;

Query OK, 0 rows affected (0.002 sec)

 

Note: A transaction commit is performed on a session



MySQL [test]> select * from t1;

+------+

| id   |

+------+

|    1 |

|    2 |

|    3 |

|    4 |

+------+

4 rows in set (0.000 sec)

 

MySQL [test]> update t1 set id = id+10;

Query OK, 5 rows affected (0.001 sec)

Rows matched: 5  Changed: 5  

Warnings: 0

 

注:执行全表更新,id+10


MySQL [test]> select * from t1;

+------+

| id   |

+------+

|   11 |

|   12 |

|   13 |

|   14 |

|   15 |

+------+

5 rows in set (0.000 sec)

 

注:当再次查看时,此时发现有5条数据被更改,产生幻读


MySQL [test]> select version();

+-----------+

| version() |

+-----------+

| 8.0.21    |

+-----------+

1 row in set (0.000 sec)

 

MySQL默认隔离级Repeatable Read下,刚才的操作,在会话二未提交的事务里,

会莫名其妙地看到第5条数据,这种现象称为幻读。


固只能通过select ... for update才能避免幻读。


Guess you like

Origin blog.51cto.com/hcymysql/2541023