访问同一数据
的多个事务的性能尽可能高 , 这时候就看二者如何权衡取舍了 。
5.1 准备数据创建一张表及数据
CREATE TABLE student ( no INT, name VARCHAR(20), age INT, PRIMARY KEY (no)) Engine=InnoDB;INSERT INTO student VALUES(1, '小明', 18);确认数据正常:
mysql> SELECT * FROM student;+----+--------+------+| no | name | age |+----+--------+------+| 1 | 小明 | 18 |+----+--------+------+1 row in set (0.00 sec)5.2 数据并发问题在并发情况下 , 如果不保证串行执行(就是一个接一个执行) , 那么会出现以下几种问题:
1. 脏写(Dirty Write)对于两个事务 Session A、Session B , 如果 Session A修改
了 Session B 修改过
但还未提交
的数据 , 就意味着发生了脏写 。
脏写示意图
发生时间编号Session ASession B①BEGIN;
②
BEGIN;③
UPDATE student SET name = '李四' WHERE no = 1;④UPDATE student SET name = '张三' WHERE no = 1;
⑤COMMIT;
⑥
ROLLBACK;已知表中仅有一条no为1、name为小明
的记录 。
Session A 与 Session B 各自开启自己的事务 , Session B 的事务先将no为1的记录修改name列的值为李四
, 然后这条记录紧接着又 Session A 给改成了张三
, 并且Session A 还 COMMIT 了 , 按理来说
此时张三
就应该永久刷写到磁盘了 , 但接着Session B 将它的事务回滚了 , 对于这记录的修改全部撤回 , 即no为1的记录的name列的值为小明
。那对于 Session A 来说就有问题了 , 明明update且commit了 , 最后一看什么变化都没有 , 这是无法被容忍的问题 , 所以在标准SQL中的四种隔离级别中都解决了脏写
的问题(就是没法复现了) 。
2. 脏读(Dirty Read)对于两个事务 Session A、Session B , 如果 Session A读取
了 Session B 修改过
但还未提交
的数据 , 之后 Session B 回滚 , 则 Session A 读到的数据就是临时且无效
的 。
脏读示意图
发生时间编号Session ASession B①BEGIN;
②
BEGIN;③
UPDATE student SET name = '李四' WHERE no = 1;④SELECR * FROM student WHERE no = 1; (如果此时读出来是李四
, 而不是小明
, 则发生了脏读)
⑤COMMIT;
⑥
ROLLBACK;已知表中仅有一条no为1、name为小明
的记录 。
Session A 与 Session B 各自开启自己的事务 , Session B 的事务先将no为1的记录修改name列的值为李四
, 然后紧接着 Session A 查询这条记录 , 如果发现读到的数据为李四
, 即读到了Session B 中还没有提交
的数据 , 之后 Session B 进行了回滚 , 数据还原回小明
, 那么 Session A 读到的李四
就是一个不存在的数据 , 这种现象称为脏读
。
在某些场合下 , 返回不存在的数据、假的数据给客户 , 是可能会出大问题的 。
3. 不可重复度(Non-Repeatable Read)对于两个事务 Session A、Session B , Session A 读取了一条记录的一个字段 , 然后 Session B
经验总结扩展阅读
- 如何打开电脑的屏幕键盘
- 四个字成语和峡有关的
- 我的 Kafka 旅程 - Producer
- Windows esp-idf 安装
- 建议收藏 Java线程同步的四种方式详解
- 历史上武则天和狄仁杰的关系
- 下 MySQL数据库-数据表
- 2023年10月21日是补墙的黄道吉日吗 2023年10月21日补墙好吗
- 乔丹的招牌动作有哪些
- 包贝尔的电影有哪些