在数据库管理系统中,脏读、不可重复读和幻读是指在事务并发执行的时候,常见的导致读操作错误的三种情况。所谓的并发事务则是指在一个数据库系统中,由于多个事务的执行时间可能出现重叠,在同一时间段内可能存在多个事务并行执行的情况。尤其是在多用户、多环境的情况下,如何能够协调多个事务之间的操作,保证数据的一致性、隔离性和持久性就成了事务并发操作的核心问题。
??而我们上面提到的三个概念就是在事务并发操作中可能出现读操作问题的情况。下面我们就来详细介绍一下这三种情况。
脏读
??脏读的意思是指一个事务读取了另一个事务还没有提交的事务,为什么会出现这种情况呢?如下所示
- 事务A更新了一条记录,但是这个时候事务A还没有来的及提交。
- 事务B就尝试读取这条数据,而此时它读取到的就是事务A修改之后的数据。
- 如果因为某些错误而导致事务A操作最终回滚了,那么事务B读到的数据显然就是一个脏数据了,因为它的数据是来源于一个已经被撤销了的数据。
??由于读取到的是还没有提交的数据,从而导致读取到的数据是不可靠的,甚至是错误的数据,为了解决这一问题,我们可以通过设置事务中的隔离级别读已提交 或更高级的隔离级别来防止脏读。
不可重复读
??从字面意思上理解,不可重复读的概念就是指在一个事务执行的过程中,读取的数据在事务内部发生了变化,也就是说事务在读取数据之后可能会遇到其他的事务修改并且提交了相同的数据,这个时候就会导致事务中读取到的数据结果不一致,如下所示。
- 事务A读取到了一条记录,已经读取到了,记住这个点
- 事务B修改并且对这条记录进行了提交操作,这个时候数据变成了新的。
- 当事务A再次读取相同的数据的时候,发现此时数据发生了变化。
??看到这里很多人都很蒙圈,这不是跟脏读一样么?其实并不是,脏读的意思是读取到了一条错误的数据。但不可重复读的意思是同一个事务重复读取了数据,然后发现数据不一致。遇到这种问题的话,我们可以通过设置隔离级别中的 可重复读 或更高级别的隔离级别来防止不可重复读问题。
幻读
??对于幻读操作来讲,是指事务在读取一组数据的时候,对于另外的事务对这组数据进行了插入、删除、修改等操作。这样就会导致第一次读取的数据结果和第二次读取的数据结果是不一致的。这种批量读取一组数据的操作经常发生在一些批量处理的过程中,如下所示。
- 事务A执行了一次查询操作,获取到了一组符合条件的数据,例如进行了一次条件查询。
- 事务B是用来插入一些符合记录条件的数据,例如插入了满足条件的一些数据。
- 这时候当事务A再次执行相同的查询操作的时候,就会发现这次获取到的数据结果集与原来的数据结果不一致了,出现了新增数据的幻影,所以被称为幻读。
??在实际操作中,我们可以通过设置串行化(Serializable) 事务级别来防止出现幻读的情况。
事务隔离级别
??事务隔离级别是数据库中用来定义并发事务如何相互之间干扰以及事务数据可见性的一种方式,所谓的隔离级别就是为了控制事务之间相互影响的等级,不同的隔离级别可能会影响到事务的并发性以及数据的一致性。
四种事务隔离级别
??根据事务的执行标准,定义了如下的四种事务隔离级别。每种隔离级别都通过不同程度的锁定或控制事务的并发性来保证数据的隔离性。不同的隔离级别对事务之间的数据交互进行不同的限制,因此它们对性能和数据一致性产生了不同的影响。
- Read Uncommitted(读未提交):允许脏读,事务之间几乎没有隔离,数据一致性最差。
- Read Committed(读已提交):防止脏读,但可能会发生不可重复读。
- Repeatable Read(可重复读):防止脏读和不可重复读,但可能会发生幻读。
- Serializable(串行化):提供最高的隔离级别,防止脏读、不可重复读和幻读,但性能较差。
总结
??事务的隔离级别决定的是多事务并发执行的时候,事务之间的数据可见性和相互干扰程度,不同的隔离级别有着不同的性能以及数据一致性保护。开发者可以根据需求来选择合适的事务隔离级别来平衡性能和一致性的需求。
本文暂时没有评论,来添加一个吧(●'◡'●)