不可重复读:在同一个事务中,对于同一份数据读取到的结果不一致。比如,事务B在事务A提交前读到的结果,和提交后读到的结果可能不同。不可重复读出现的原因就是事务并发修改记录,要避免这种情况,最简单的方法就是对要修改的记录加锁,在事物B操作的时候,给记录加锁,A无法写入,这会导致锁竞争加剧,影响性能。另一种方法是通过MVCC可以在无锁的情况下,copy一个快照进行修改。避免不可重复读。
幻读:在同一个事务中,同一个查询多次返回的结果不一致。事务A新增了一条记录,事务B在事务A提交前后各执行了一次查询操作,发现后一次比前一次多了一条记录。幻读是由于并发事务增加记录导致的,这个不能像不可重复读通过记录加锁解决,因为对于新增的记录根本无法加锁。这个是往里面加入一个新的纪录,没法和以前一样在记录上加锁,需要将事务串行化,读写分离,才能避免幻读。但是可以利用gap lock来解决问题一个数据库,你可以简单的认为一个文件系统。应对高并发的读,写,修改,删除,自然会带来很多的不一致的问题。如何读的同时处理有人正在进行写入。mvcc根据的正是利用快照,于是存在数据库的多种版本,不同的时刻的操作对应着不同的数据库的版本。脏数据问题,幻读的问题。
在修改的时候,有些数据库可以进行排队(serializable),读写分离,可以解决并发,但是效率和延时会因此上升。如果采用加锁的原则,那么会相应的利用表锁,页锁定以及行锁,锁之间自然会存在抢占资源,等待问题,造成的死锁。有些干脆复制一份数据,写入的时候就是在这个快照上面就行修改,然后进行提交,但是大量的复制自然会造成效率的下降。