数据库事务机制
ACID原则
事务机制遵循ACID原则:
Atomicity
原子性:事务是一个原子操作,由一系列操作组成。事务的原子性确保所有操作要么完成,要么完全不起作用(完整性)。Consistency
一致性:事务执行前后,系统必须确保它所建模的业务处于一致的状态。例如转账,无论事务是否成功,转账者和收款人的总额应该不变。Isolation
隔离性:并发操作相同的数据时,各事务之间相互独立。(但难免会存在冲突)Durability
持久性:一旦事务完成,它对数据的改变是持久的,即使数据库发生故障也不影响持久性。
只有保证了事务的持久性、原子性、隔离性之后,一致性才能得到保障(A、I、D是手段,C是目的)。
隔离级别
为了解决并发处理相同数据时,事务之间存在冲突的问题,事务有一套隔离机制,设置了隔离级别:
READ_UNCOMMITTED
读未提交其他事务会读取当前事务尚未提交的更改(暂时缓存的内容)
READ_COMMITTED
读已提交其他事务会读取当前事务已经提交的数据(直接读取数据库中已发生更改的内容)
REPEATABLE_READ
可重复读其他事务会读取当前事务已经提交的数据,并且其他事务执行过程中不允许再进行数据修改。
ISOLATION_SERIALIZABLE
串行化完全服从ACID原则,一个事务必须等待其他事务结束之后才能开始执行,效率很低。
READ_UNCOMMITTED 读未提交
各个事务共享一个缓存区域,其他事务会读取当前事务尚未提交的更改(暂时缓存的内容),这样的更改是可以被回滚的。如图事务A读取的数据就是一个毫无意义的脏数据。这种现象之为脏读。
READ_COMMITTED 读已提交
读已提交避免了脏读的问题,但是如果当前事务在其他事务2次读取相同数据之间,修改并提交了数据,会导致两次读取结果不一致。这种现象称为不可重复读。
READ_REPEATABLE 可重复读 (默认)
可重复读是MySQL的InnoDB存储引擎的默认隔离级别。它规定在其他事务执行时,当前事务不允许修改数据。
这样可以有效避免不可重复读的问题,但是仍然不安全。仅仅是禁止了事务执行过程中的UPDATE操作,没有禁止INSERT操作。这样在同一个事务中,第一次和第二次查询同一个范围的数据,如果有其他事务插入了新的数据,就会导致返回的结果不一致。这种现象称为幻读。
ISOLATION_SERIALIZABLE 串行化
一个事务必须等待其他事务结束之后才能开始执行,效率很低。