隔离级别
当试图维持一个高的隔离级别时,DBMS通常要求对数据进行加锁或者实现多版本并发控制(MVCC)。大多数情况下的应用场景其实是尽量避免高隔离级别,以获取高的并发性能,但是程序员也需要保证降低隔离级别不会导致软件bug,所以有四种隔离级别。
串行化/可序列化
这是最高隔离级别。
如果并行控制是基于锁实现的话,串行化要求获得(所选数据的)读锁和写锁,这两个锁在事务的最后会被释放。当然SELECT语句使用WHERE从句时,还需要一个范围锁(range-lock),以避免幻读(phantom reads),即无法向这个范围内插入新的记录。
如果并行控制不是基于锁的实现,则不需要获得锁。然而,这种情况下,如果系统探测到一个在多个并行事务中存在写冲突,那只允许一个事务提交。可以搜索快照隔离(Snapshot)的有关主题。
可重复读
如果并行控制基于锁的实现,可重复读持有(所选数据的)读锁和写锁,直到事务结束释放这两个锁,但是,可重复读并不保持范围锁,所以无法避免幻读,即可以向这个范围内插入新的记录。
读提交
在基于锁实现的并行控制下,读提交保持着(所选数据的)写锁直到事务结束释放写锁,但是读锁则在SELECT操作执行(而非整个事务结束)完成后就释放,这意味着这个隔离级别下同一个事务中先后两次读取的数据可能会不一样,即发生不可重复读。由于对所选数据保持着写锁,故在事务结束前还未释放这个写锁,其他事务则无法获取这个事务中变化后的新数据,即,只能读取提交的数据而不能读取未提交的数据(保证不会“脏读”)。
简单来说,这个级别保证读取数据的时刻,被读取的数据时已经提交的,不会读取到中间过程的、未提交的数据,但是无法保证如果事务重新读取数据还能读取相同的数据,因为在读取数据结束时,数据已经自由了(没有被锁)。
跟上一个级别相同,这个级别下也不会有范围锁。
读未提交
这是最低的隔离级别。这个级别下会发生“脏读”,在一个事务中可能会看到一些由其他事务引起的 not-yet-committed的变化。