SQL的事务( 三 )

访问同一数据的多个事务的性能尽可能高 , 这时候就看二者如何权衡取舍了 。
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

经验总结扩展阅读