原理"/>
脏写 脏读 不可重复读 幻读的原理
一、脏写、脏读
出现脏写的情况,主要原因是俩个事务,事务A和事务B同时更新一条数据,事务A先把数据更新为A值,此时会在undo log日志文件记录一下,同时也会在redo log中记录这个举动,事务B接着把数据更新为B,此时一样会在undo log,redo log日志中记录。此时看到的数据值为B,如果事务A突然回滚,那么可以根据刚刚undo log日志进行回滚操作。这样数据就会变成null值,而不是B,对于B而言这种情况就属于脏写了,B俩次读到不同的值的情况就属于脏读。简单点就是:
脏写:俩个事务没有提交的情况下,都修改同一条数据,结果一个事务回滚了,把另一个事务修改的值也给撤销了,所谓脏写就是俩个事务没提交状态下修改同一个值。
脏读:一个事务修改了一条数据的值,还没有提交事务,另外一个事务就读到你修改的值,然而之后事务回滚了,人家再次读取的时候值变了,也就是说人家读到了你修改之后还没提交的值。
二、不可重复读
假设缓存页里有一条数据原来的值是A,此时事务A开启之后,第一次查询这条数据,读取到的就是A,接着事务B更新了那条数据的值为B,同时事务B立马提交了,然而事务A还没有提交。事务A读取到的值现在是B,接下来事务C将数据更新为C值并且提交了事务,此时A事务还是没有提交。此时查询的数据值为C。
如上所说,现在的值是C,事务A第一次读取的值为A,那么他可能希望的是在事务执行期间,如果多次查询数据都应该通用是A,就是这个值是可重复读的--一直是A值,而不是C值。不可重复读简单而言:一个事务多次查询一条数据,结果每次读到的值都是不一样的,这个过程中可能别的事务会修改这条数据的值,而且修改之后事务都提交了,导致每次查询的值都不一样,都是查询到了提交事务之后的值。
三、幻读
事务A查询数据的个数为2条,接着事务B插入了2条数据并且提交事务。此时事务A查询出来的数据个数就变成4条。此时事务A因为俩次查询出数据的个数不同的情况就是幻读了。简而言之:一个事务用一个的sql语句多次查询,结果每次查询都会查询到之前没查到的数据。
通过上面对脏读、脏写、不可重复读、幻读的讲解,基本上这些情况都是因为多线程并发执行导致的。数据库为了解决上面的情况,设计了事务隔离机制、MVCC多版本隔离机制、锁机制,用一整套机制来解决多事务并发的问题。
借道友法力一用:
========================== stay hungry stay foolish =============================
更多推荐
脏写 脏读 不可重复读 幻读的原理
发布评论