云计算、AI、云原生、大数据等一站式技术学习平台

网站首页 > 教程文章 正文

数据库脏读、脏写、不可重复读和幻读的区别

jxf315 2024-12-22 19:05:10 教程文章 36 ℃

当业务系统访问数据库时,往往有多个线程并发执行多个事务对数据库进行读写等操作。对于数据库来说,当有多个事务并发对数据库中的数据执行相关操作时就会涉及到多个事务对同一条数据进行更新或者查询操作。如果没有针对性地设计好事务之间的并发机制,制定好数据访问策略,那么就会导致一些问题的产生,常见的数据库访问问题归类为以下四类:脏读、脏写、不可重复读幻读。所以数据库的高并发问题的解决对数据库技术具有重要意义。

脏读

所谓脏读,我个人理解是所读取的数据是“脏”的,或者说是不真实的,不具有真实性。举个例子,假设有事务T1和T2在并发地对同一个数据库中的同一条数据进行操作。如下图1所示, T1执行的是更新数据操作,并且执行完后还没有提交(因为我们知道数据库操作只有提交完后才能落盘保证数据的真实性),此时事务T2对未提交的数据进行了读取操作。然后事务T1由于某种原因进行了回滚(撤销更新数据的操作),那么此时造成了事务T2读取到的数据无效了,也就是不具有真实性,是一条脏数据,以上所述就称为数据脏读。

脏写

所谓脏写,我个人理解是一个事务更新数据库中的值后更新的值无效,或者说更新了数据库中某一条记录却没有显示出修改后的值。如下如图2所示,T1执行更新数据操作,把原本是NULL的值更新为A值,但此时其还未提交(因为我们知道数据库操作只有提交完后才能落盘保证数据的真实性),此时事务T2接着执行更新数据操作,把A值修改为了B值。然后事务T1由于某种原因进行了回滚(撤销更新数据的操作),导致数据变回NULL,那么此时事务T2执行的写更新的操作无效了。脏写的本质就是事务 T2 去修改了事务 T1 修改过的值,但是此时事务 T1 还没提交,所以事务 T1 随时会回滚,导致事务 T2 修改的值也没了。

不可重复读

所谓不可重复读,指的是事务在一段时间内读取同一条数据时显示了不同的结果。如下图3所示,事务T1第一次读取了数据值为A,紧接着事务T2修改了T1刚才读取的那一行记录并且提交了。然后T1第二次读取这行记录,发现与刚才读取的结果不同,这就称为不可重复读,因为T1原来读取的那行记录已经发生了变化。接着如果有其他数据接着对值进行更新那么事务T1后续读取的值都不一样。

幻读

所谓幻读,可以理解为在执行SQL语句时好像出现了“幻觉”一样,以select语句为例。如下图4所示,事务T1在首次使用select语句查询时,如使用如下语句进行查询操作:

select * FROM table WHERE id > 2

假设一开始的原始数据中满足条件的选出了5条数据,然后事务T2执行了更新或者添加数据操作并进行了提交。然后事务T1接着执行上述一样的SQL语句时查询到了具有10条数据的记录,此时的事务T1前后两次执行一样的语句却出现了不同的结果,这就好比出现了“幻觉”一样,这就是幻读的定义。

最后总结:脏读、脏写、不可重复读和幻读其实都是因为业务系统会多线程并发执行访问数据库,而每个线程都会开启一个事务,每个事务都会执行增、删、改或者查的操作。数据库在并发执行多个事务时,会出现不同事务的执行顺序不同从而也就导致了上述四种状况的发生。所以在设计一个满足业务需求的数据库时,我们要重点关注事务之间执行的顺序问题。

最近发表
标签列表