Mysql隔离级别演示


一. 准备工作

本文章是基于MySQL8.0下演示,开启俩个窗口,为了方便说明,下面我会使用事务1和事务2来演示

1.1 准备表

mysql> select * from student;
+----+------+------+
| id | name | tid  |
+----+------+------+
|  3 | 小张 |    1 |
|  1 | 小明 |    1 |
|  2 | 小红 |    1 |
|  4 | 小李 |    2 |
|  5 | 小王 |    2 |
+----+------+------+
5 rows in set (0.00 sec)

1.2 查看事务隔离级别

mysql> show variables like 'transaction%';
+----------------------------------+-----------------+
| Variable_name                    | Value           |
+----------------------------------+-----------------+
| transaction_alloc_block_size     | 8192            |
| transaction_allow_batching       | OFF             |
| transaction_isolation            | REPEATABLE-READ |
| transaction_prealloc_size        | 4096            |
| transaction_read_only            | OFF             |
| transaction_write_set_extraction | XXHASH64        |
或使用
mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ         |
+-------------------------+

1.3 修改自动提交配置

mysql> show variables like '%autocommit%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit    | ON    |
+---------------+-------+
1 row in set, 1 warning (0.00 sec)

mysql> set autocommit = off;
Query OK, 0 rows affected (0.00 sec)

二、在读未提交的隔离级别下

2.1 修改隔离级别

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

2.2 代码演示

对事务1进行修改操作,不提交事务

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

事务2进行查询操作

mysql> select * from student;
+----+------+------+
| id | name | tid  |
+----+------+------+
|  3 | 小张 |    1 |
|  2 | 小红 |    1 |
|  1 | 小黑 |    1 |
|  4 | 小李 |    2 |
|  5 | 小王 |    2 |
+----+------+------+
5 rows in set (0.00 sec)

2.3 总结

通过代码演示可以看出,事务1对数据进行了修改操作,但没有提交事务,这时,事务2进来,对数据进行了查询操作,查询到了事务1没有提交的数据.这就是脏读产生的原因.脏读只会在读未提交下产生.

三、在读已提交的隔离级别下

3.1 修改隔离级别

mysql> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)

3.2 代码演示

事务1进行修改操作,并不提交事务

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

事务2进行查询操作

mysql> select * from student;
+----+------+------+
| id | name | tid  |
+----+------+------+
|  3 | 小张 |    1 |
|  2 | 小红 |    1 |
|  1 | 小黑 |    1 |
|  4 | 小李 |    2 |
|  5 | 小王 |    2 |
+----+------+------+
5 rows in set (0.00 sec)

总结
可以看出,在读已提交的隔离级别下,对事务1进行了修改,事务2没有查询到修改的数据,这样就避免了会读到脏数据的,解决了脏读问题。但不能避免不可重复读问题,下面我会通过代码继续演示。

事务1进行修改操作,并未提交事务

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

这时,事务2进行读取数据

mysql> select * from student;
+----+------+------+
| id | name | tid  |
+----+------+------+
|  3 | 小张 |    1 |
|  2 | 小红 |    1 |
|  1 | 小黑 |    1 |
|  4 | 小李 |    2 |
|  5 | 小王 |    2 |
+----+------+------+
5 rows in set (0.00 sec)

事务1提交了事务

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

事务2再次读取数据

mysql> select * from student;
+----+------+------+
| id | name | tid  |
+----+------+------+
|  3 | 小张 |    1 |
|  2 | 小红 |    1 |
|  1 | 小蓝 |    1 |
|  4 | 小李 |    2 |
|  5 | 小王 |    2 |
+----+------+------+
5 rows in set (0.00 sec)

3.4 总结

在读已提交的隔离级别下,虽然解决了不可重复读的问题,但是没有解决不可重复读的问题,不可重复读就是事务2在事务1提交前读取到的数据,与 事务1提交后读取的数据不一致.

四 在可重复读的隔离级别下

4.1 修改隔离级别

mysql> set session transaction isolation level repeatable read;
Query OK, 0 rows affected (0.00 sec)

4.2代码演示

事务1进行修改操作,并未提交事务

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

事务2读取数据

mysql> select * from student;
+----+------+------+
| id | name | tid  |
+----+------+------+
|  3 | 小张 |    1 |
|  2 | 小红 |    1 |
|  1 | 小蓝 |    1 |
|  4 | 小李 |    2 |
|  5 | 小王 |    2 |
+----+------+------+
5 rows in set (0.00 sec)

事务1提交事务

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

事务2读取数据

mysql> select * from student;
+----+------+------+
| id | name | tid  |
+----+------+------+
|  3 | 小张 |    1 |
|  2 | 小红 |    1 |
|  1 | 小蓝 |    1 |
|  4 | 小李 |    2 |
|  5 | 小王 |    2 |
+----+------+------+
5 rows in set (0.00 sec)

总结
可以看出,在可重复读的隔离级别下,没有产生脏读,不可重复读的问题,但有可能产生幻读的问题.下面我会通过代码进行演示.
事务2查询 name=小紫 的数据

mysql> select * from where name = '小紫';
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where name = '小紫'' at line 1

事务1插入一条 name=小紫 的数据,并提交事务

mysql> insert into student value('6','小紫','2');
Query OK, 1 row affected (0.00 sec)

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

事务2再去查询 name=小紫 的数据

mysql> select * from where name = '小紫';
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where name = '小紫'' at line 1

事务2插入一条 name=小紫 的数据

mysql> insert into student value('6','小紫','2');
ERROR 1062 (23000): Duplicate entry '6' for key 'PRIMARY'

总结

时间点事务2事务1
1开启事务
2开启事务
3查询数据“小紫”,不存在
4插入数据“小紫”
5提交事务
6查询数据“小紫”,不存在
7插入数据“小紫”,不成功

总结

下面我总结了各种隔离级别下可能出现的问题.
在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL隔离级别包括读未提交(read uncommitted)、读已提交(read committed)、可重复读(repeatable read)和串行化(serializable)。读未提交的隔离级别允许一个事务读取到其他事务未提交的数据,这可能导致脏读问题。设置事务的全局隔离级别为读未提交可以使用以下语句:`set global transaction isolation level read uncommitted;`[2]。读已提交的隔离级别要求一个事务只能读取到其他事务已经提交的数据,避免了脏读问题。设置事务的全局隔离级别为读已提交可以使用以下语句:`set global transaction isolation level read committed;`[1]。可重复读是MySQL的默认隔离级别,它解决了不可重复读问题,即同一事务内多次读取同一数据得到的结果不会发生变化。然而,可重复读隔离级别引入了幻读问题,即虽然事务二已经提交,但事务一仍然读取到的是事务一开始时的数据。这可能导致事务一读取到额外的行或者未读取到已经存在的行。。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [MySQL数据库四种隔离级别演示](https://blog.csdn.net/qq_36867807/article/details/115697664)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值