并行事务会引发什么问题?

并行事务会引发什么问题?

MySQL 服务端是允许多个客户端连接的,这意味着 MySQL 会出现同时处理多个事务的情况。

那么在同时处理多个事务的时候,就可能出现脏读(dirty read)、不可重复读(non-repeatable read)、幻读(phantom read)的问题

接下来,通过举例子给大家说明,这些问题是如何发生的。

脏读

如果一个事务「读到」了另一个「未提交事务修改过的数据」,就意味着发生了「脏读」现象。

不可重复读

在一个事务内多次读取同一个数据,如果出现前后两次读到的数据不一样的情况,就意味着发生了「不可重复读」现象。

幻读

在一个事务内多次查询某个符合查询条件的「记录数量」,如果出现前后两次查询到的记录数量不一样的情况,就意味着发生了「幻读」现象。

事务A:

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

mysql> insert into user values(1522158666475192324,'testtt','test','1','test','test',0);
Query OK, 1 row affected (0.00 sec)

mysql> select * from user;
+---------------------+--------------+-------------+------+-----------+--------+--------+
| id                  | name         | phone       | sex  | id_number | avatar | status |
+---------------------+--------------+-------------+------+-----------+--------+--------+
| 1522158666475192321 | 我是谁??? | 13571761373 | NULL | NULL      | NULL   |      1 |
| 1522158666475192323 | test         | test        | 1    | test      | test   |      0 |
| 1522158666475192324 | testtt       | test        | 1    | test      | test   |      0 |
+---------------------+--------------+-------------+------+-----------+--------+--------+

mysql> commit;

事务B:

mysql> start transaction;
mysql> select * from user;
+---------------------+--------------+-------------+------+-----------+--------+--------+
| id                  | name         | phone       | sex  | id_number | avatar | status |
+---------------------+--------------+-------------+------+-----------+--------+--------+
| 1522158666475192321 | 我是谁??? | 13571761373 | NULL | NULL      | NULL   |      1 |
| 1522158666475192323 | test         | test        | 1    | test      | test   |      0 |
+---------------------+--------------+-------------+------+-----------+--------+--------+
2 rows in set (0.11 sec)

mysql> select * from user for update;
+---------------------+--------------+-------------+------+-----------+--------+--------+
| id                  | name         | phone       | sex  | id_number | avatar | status |
+---------------------+--------------+-------------+------+-----------+--------+--------+
| 1522158666475192321 | 我是谁??? | 13571761373 | NULL | NULL      | NULL   |      1 |
| 1522158666475192323 | test         | test        | 1    | test      | test   |      0 |
| 1522158666475192324 | testtt       | test        | 1    | test      | test   |      0 |
+---------------------+--------------+-------------+------+-----------+--------+--------+
3 rows in set (33.73 sec)

-- 或者
mysql> update user set name = 'up' where id = 1522158666475192324;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
mysql> select * from user;
+---------------------+--------------+-------------+------+-----------+--------+--------+
| id                  | name         | phone       | sex  | id_number | avatar | status |
+---------------------+--------------+-------------+------+-----------+--------+--------+
| 1522158666475192321 | 我是谁??? | 13571761373 | NULL | NULL      | NULL   |      1 |
| 1522158666475192323 | test         | test        | 1    | test      | test   |      0 |
| 1522158666475192324 | up           | test        | 1    | test      | test   |      0 |
+---------------------+--------------+-------------+------+-----------+--------+--------+
3 rows in set (0.09 sec)

执行顺序:

B:select * from user; -- 结果两条记录
A:insert into user values();  -- 未提交
B:select * from user for update; -- 结果三条记录,查当前(for update)
-- 或
B:update user set name = 'up' where id = 1522158666475192324;
B:select * from user; -- 结果三条记录,因为上条更新语句会先查全表数据

-- 对于事务B来说出现了幻觉,这种现象即为幻读。在同一事务中,相同查询条件记录数不同。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值