一, 事务 (Transaction) 的基本要素 (ACID)
1, 原子性 (Atomicity): 事务开始后所有操作, 要么全部做完, 要么全部不做, 不可能停滞在中间环节. 事务执行过程中出错, 会回滚到事务开始前的状态, 所有的操作就像没有发生一样. 也就是说事务是一个不可分割的整体, 就像化学中学过的原子, 是物质构成的基本单位.
2, 一致性 (Consistency): 事务开始前和结束后, 数据库的完整性约束没有被破坏 . 比如 A 向 B 转账, 不可能 A 扣了钱, B 却没收到.
3, 隔离性 (Isolation): 同一时间, 只允许一个事务请求同一数据, 不同的事务之间彼此没有任何干扰. 比如 A 正在从一张银行卡中取钱, 在 A 取钱的过程结束前, B 不能向这张卡转账.
4, 持久性 (Durability): 事务完成后, 事务对数据库的所有更新将被保存到数据库, 不能回滚.
二, 并发访问会导致的问题
脏读: 指一个线程中的事务读取到了另外一个线程中未提交的数据;
ex: 事务 A select data = 100, 事务 B 此时更新 data = 200, 还未提交, 事务 A 再次 select data = 200, 如果事务 B 回滚, 那么 A 得到的 200 就是脏数据.
不可重复读 (虚读): 指一个线程中的事务读取到了另外一个线程中提交的 update 的数据; 该现象由事务更新造成;
ex: 事务 A select data 发现 data = 100, 此时事务 B 更新 data = 200 并提交, 事务 A 又 select data 发现此时 data 从 100 变成了 200, 数据出现了不一致现象.
幻读: 指一个线程中的事务读取到了另外一个线程中提交的 insert or delete 的数据; 该现象由事务删除或者新增造成;
ex: 事务 A select data 发现数据 data 不存在, 于是准备 insert data, 事务 B 在 A 事务之前 insert data 导致事务 A insert data 失败, 事务 A 好像幻觉一样, 怎么 data 出现了?
三, 隔离 (Isolation) 级别简介
1, 读未提交 READ-UNCOMMITTED: 一个事务可以读另一个事务未提交的数据; 该隔离级别会导致脏读, 不可重复读取现象, 幻读;
2, 读已提交 READ-COMMITTED: 一个事务只能读另一个事务提交的数据; 该隔离级别会导致不能重复读取和幻读现象; 解决了脏读现象;
3, 可重复读 REPEATABLE-READ: 一个事务可重复读另一个事务提交的数据; 该隔离级别会导致幻读现象; 解决了脏读现象和不能重复读取的现象;
4, 序列化 SERIALIZABLE: 该隔离级别解决所有并发访问会导致的问题, 解决了脏读现, 不可重复读现和幻读现象;
PS: 不可重复读的和幻读很容易混淆, 不可重复读侧重于修改, 幻读侧重于新增或删除. 解决不可重复读的问题只需锁住满足条件的行, 解决幻读需要锁表
补充:
1, 事务隔离级别为读提交时, 写数据只会锁住相应的行
2, 事务隔离级别为可重复读时, 如果检索条件有索引 (包括主键索引) 的时候, 默认加锁方式是 next-key 锁; 如果检索条件没有索引, 更新数据时会锁住整张表. 一个间隙被事务加了锁, 其他事务是不能在这个间隙插入记录的, 这样可以防止幻读.
3, 事务隔离级别为串行化时, 读写数据都会锁住整张表
4, 隔离级别越高, 越能保证数据的完整性和一致性, 但是对并发性能的影响也越大.
5,MySQL MVCC 实现机制参考链接: https://blog.csdn.net/whoamiyang/article/details/51901888
6, 关于 next-key 锁可以参考链接: https://blog.csdn.net/bigtree_3721/article/details/73731377
来源: http://www.bubuko.com/infodetail-2983373.html