4.1 事务
什么是事务
一个事务是可以被看作一个单元的一系列SQL语句的集合。它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。
事务的特性(ACID)
- 原子性(atomacity):事务是一个不可再分割的工作单位,事务中的操作要么都发生,要么都不发生
- 一致性(consistency):事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
- 隔离性(isolation):一个事务不应该影响其它事务运行效果。一个事务的影响在该事务提交前对其他事务都不可见。
- 持久性(durability):在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。
并发控制
并发控制的主要方法是封锁(Locking)。
读写异常
- 脏读(Dirty Read):事务A修改某个数据并写回磁盘,事务B读取同一数据,但A由于某种原因撤销了,这时B修改过的数据恢复原来的值,A读取的数据就与数据库中的数据不一致。
- 非重复读(Nonrepeatable Read):事务A读取数据后,事务B执行更新操作,使A无法再次读取结果。
- 幻读(Phantom Reads):事务在操作过程中进行两次查询,第二次查询结果包含了第一次查询中未出现的数据(这里并不要求两次查询SQL语句相同)这是因为在两次查询过程中有另外一个事务插入数据造成的。
- 丢失修改(Lost Update):两个事务A,B读入同一数据并修改,B提交的结果被A破坏了,导致B的修改丢失。
事务的隔离级别
- 未提交读(Read Uncommitted):事务可以看到其他事务“尚未提交”的修改。
- 提交读(Read Committed):这可以通过“瞬间共享读锁”和“排他写锁”实现。读取数据的事务允许其他事务继续访问该行数据,但是未提交的写事务将会禁止其他事务访问该行。
- 可重复读(Repeatable Read):这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许读事务),写事务则禁止任何其他事务。
- 可序列化(Serializable):这个事务执行的时候不允许别的事务并发执行。事务只能一个接着一个地执行。仅仅通过“行级锁”是无法实现事务序列化的,必须通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。
隔离级别 | 脏读 | 非重复读 | 幻读 | 丢失修改 | 加锁读 |
---|---|---|---|---|---|
未提交读 | YES | YES | YES | YES | NO |
提交读 | NO | YES | YES | YES | NO |
可重复读 | NO | NO | YES | NO | NO |
可序列化 | NO | NO | NO | NO | YES |