并发一致性问题
在并发环境下, 事务的隔离性很难保证, 因此会出现一些并发一致性问题.
问题
- 脏读 T1修改了一个数据, T2随后读取了这个数据, 如果T1撤销了这次修改, 那么T2读取的数据是脏数据. 因为T1的修改并没有commit到数据库, 但是这个事务对别的事务可见.
- 不可重复读 T1中多次读取一个数据过程中, 由于T2对数据进行了修改, 并提交了事务, 因此T1前后读的到的相同数据的值不相同.
- 幻读 T1读取了某个范围的数据, T2在这个范围插入了新的数据, T1再次读的时候, 发现在这个范围中还有没有读取的数据, 像是幻觉.
不可重复读与幻读区别
不可重复读的关键是对某一行的修改, 幻读的关键在于插入.
如果用锁机制来实现两种隔离, 在可重复读中, 第一次读取数据时就应该对数据加锁, 其他事务无法对其进行修改. 但是这无法保证对幻读的隔离. 对于幻读, 需要serializable隔离级别, 用读写锁进行修饰, 但是这样会降低并发能力.
隔离级别
- 未提交读 事务中的修改, 即使没有提交, 对其他事务也可见.
- 提交读 一个事务只能读取已经提交的事务所做的修改. 也就是说, 一个事务在提交前, 对其他事务是不可见的.
- 可重复读 保证在同一个事务中多次读取同个数据的结果是一样的.
- 可串行化 强制事务串行化执行.
隔离级别 | 脏读 | 不可重复读 | 幻影读 |
---|---|---|---|
未提交读 | YES | YES | YES |
提交读 | NO | YES | YES |
可重复读 | NO | NO | YES |
可串行化 | NO | NO | NO |