前言
事务的四大特性(简称ACID)。数据库如果支持事务的操作,那么就具备以下四个特性:
1. 原子性(Atomicity)
– 事务是数据库的逻辑工作单位,事务中包括的诸操作要么全做,要么全不做。
- 一致性(Consistency)
- 事务执行的结果必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
- 隔离性(Isolation)
- 一个事务的执行不能被其他事务干扰。
- 持续性/永久性(Durability)
- 一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。
一、一致性
- 强一致性:读操作可以立即读到提交的更新操作。
- 弱一致性:提交的更新操作,不一定立即会被读操作读到,此种情况会存在一个不一致窗口,指的是读操作可以读到最新值的一段时间。
- 最终一致性:是弱一致性的特例。事务更新一份数据,最终一致性保证在没有其他事务更新同样的值的话,最终所有的事务都会读到之前事务更新的最新值。如果没有错误发生,不一致窗口的大小依赖于:通信延迟,系统负载等。
- 其他一致性变体还有:
- 单调一致性:如果一个进程已经读到一个值,那么后续不会读到更早的值。
- 会话一致性:保证客户端和服务器交互的会话过程中,读操作可以读到更新操作后的最新值。
二、隔离性
mysql四种隔离级别是:
1. Serializable (串行化)
2. Repeatable read (可重复读)
3. Read committed (读已提交)
4. Read uncommitted (读未提交)
读数据库时候可能发生的三种问题:
1. 脏读
事务A修改了一个数据,但未提交,事务B读到了事务A未提交的更新结果,如果事务A提交失败导致回滚,事务B读到的就是脏数据。
2. 不可重复读
在同一个事务中,对于同一份数据读取到的结果不一致。比如,事务B在事务A提交前读到的结果,和提交后读到的结果可能不同。不可重复读出现的原因就是事务并发修改记录,要避免这种情况,最简单的方法就是对要修改的记录加锁,这回导致锁竞争加剧,影响性能。另一种方法是通过MVCC可以在无锁的情况下,避免不可重复读。
3. 幻读
在同一个事务中,同一个查询多次返回的结果不一致。事务A新增了一条记录,事务B在事务A提交前后各执行了一次查询操作,发现后一次比前一次多了一条记录。幻读是由于并发事务增加记录导致的,这个不能像不可重复读通过记录加锁解决,因为对于新增的记录根本无法加锁。需要将事务串行化,才能避免幻读。
数据库的隔离级别,与读数据可能出现的三种问题之间的对应关系如下
级别 | 中文 | 英文 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|---|---|
0 | 读未提交 | Read uncommitted | 可能 | 可能 | 可能 |
1 | 读已提交 | Read committed | 不可能 | 可能 | 可能 |
2 | 可重复读 | Repeatable read | 不可能 | 不可能 | 可能 |
3 | 串行化 | Serializable | 不可能 | 不可能 | 不可能 |
总结
- 以上四种隔离级别最高的是Serializable级别,最低的是Read uncommitted级别,级别越高,执行效率就越低。
- 要避免不可重复读,最简单的方法就是对要修改的记录加锁,这回导致锁竞争加剧,影响性能。另一种方法是通过MVCC可以在无锁的情况下,避免不可重复读。
- 幻读是由于并发事务增加记录导致的,这个不能像不可重复读通过记录加锁解决,因为对于新增的记录根本无法加锁。需要将事务串行化,才能避免幻读。
- 数据库以及所使用的框架不同,会导致实际可以使用的级别不同。
参考
http://xzh.i3geek.com
0 条评论