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

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来说出现了幻觉,这种现象即为幻读。在同一事务中,相同查询条件记录数不同。

原文地址:http://www.cnblogs.com/malongfeistudy/p/16796937.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性