没有数据库的事务隔离,会出现以下各种问题:
脏读
一个客户端读取到另一个客户端尚未提交的写入。读已提交或更强的隔离级别可以防止脏读。
脏写
一个客户端覆盖写入了另一个客户端尚未提交的写入。几乎所有的事务实现都可以防止脏写。
读取偏差(不可重复读)
在同一个事务中,客户端在不同的时间点会看见数据库的不同状态。快照隔离经常用于解决 这个问题,它允许事务从一个特定时间点的一致性快照中读取数据。快照隔离通常使用多版本并发控制(MVCC) 来实现。
更新丢失
两个客户端同时执行读取-修改-写入序列。其中一个写操作,在没有合并另一个写入变更情况下,直接覆盖了另一个写操作的结果。所以导致数据丢失。快照隔离的一些实现可以自动防止这种异常,而另一些实现则需要手动锁定(SELECT FOR UPDATE )。
写偏差
一个事务读取一些东西,根据它所看到的值作出决定,并将决定写入数据库。但是,写入的 时候,决定的前提不再是真实的。只有可序列化的隔离才能防止这种异常。
例子:会议室预订、多人棋盘游戏、抢注用户名、防止双重开支。
Alice和Bob是两位值班医生。两人都感到不适,所以他们都决定请假。不幸的是,他们恰好在同一时间点击按钮下班。
在两个事务中,应用首先检查是否有两个或以上的医生正在值班;如果是的话,它就假定一 名医生可以安全地休班。由于数据库使用快照隔离,两次检查都返回 2 ,所以两个事务都进 入下一个阶段。Alice更新自己的记录休班了,而Bob也做了一样的事情。两个事务都成功提 交了,现在没有医生值班了。违反了至少有一名医生在值班的要求。
幻读
一个事务中的写入改变另一个事务的搜索查询的结果,被称为幻读。
事务读取符合某些搜索条件的对象。另一个客户端进行写入,影响搜索结果。快照隔离可以 防止直接的幻像读取,但是写入歪斜环境中的幻影需要特殊处理,例如索引范围锁定。
参考
https://www.jianshu.com/p/69fd2ca17cfd
https://www.jianshu.com/p/db334404d909