可重复读隔离级别下依旧出现幻读的场景

幻读:同一个查询在不同时刻查询到的结果集不同

场景:

(1):对于快照读来说—在可重复读隔离级别下,事务 A 第一次执行普通的 select 语句时生成了一个 ReadView,之后事务 B 向表中新插入了一条 id = 6 的记录并提交。接着,事务 A 对 id = 6 这条记录进行了更新操作,在这个时刻,这条新记录的 trx_id 隐藏列的值就变成了事务 A 的事务 id,之后事务 A 再使用普通 select 语句去查询这条记录时就可以看到这条记录了,于是就发生了幻读。

首先update,delete,insert操作都会将当前事务id回写到记录行中,如果在同一个事务里一开始没有显式的使用当前读方式,而是在update,insert,delete后再次进行快照读,都有可能在mvcc模式下产生幻读。

(2)对于当前读来说—如果事务开启后,并没有执行当前读,而是先快照读,然后这期间如果其他事务插入了一条记录,那么事务后续使用当前读进行查询的时候,就会发现两次查询的记录条目就不一样了,所以就发生幻读。

要避免这类特殊场景下发生幻读的现象的话,就是尽量在开启事务之后,马上执行 select ... for update 这类当前读的语句,因为它会对记录加 next-key lock,从而避免其他事务插入一条新记录。

### 回答1: 数据库事务的四种级别是: 1. 未提交(Read Uncommitted):在该级别下,事务可以取其他事务未提交的数据。这种级别不保证事务的隔离性,存在脏、不可重复的问题。 2. 已提交(Read Committed):在该级别下,事务只能取已经提交的数据。这种级别能够避免脏的问题,但仍然存在不可重复的问题。 3. 可重复(Repeatable Read):在该级别下,事务在整个过程中可以多次取同一数据,并且每次取的数据都是一致的。这种级别能够避免脏和不可重复的问题,但仍然存在的问题。 4. 串行化(Serializable):在该级别下,所有事务都必须串行执行,即一个事务必须等待前一个事务结束之后才能开始执行。这种级别能够完全避免脏、不可重复的问题,但由于事务串行执行,会导致性能下降。 举个例子,假设有两个事务 A 和 B,A 事务想要修改表中的一条记录,B 事务想要取这条记录的值。在不同的事务隔离 ### 回答2: 数据库事务的四种级别分别是:未提交(Read Uncommitted)、提交(Read Committed)、可重复(Repeatable Read)和串行化(Serializable)。 1. 未提交:允许事务取其他事务未提交的数据,可能会出现脏(dirty read)的问题。例如,用户A正在执行事务并更新某行数据,此时用户B取到了用户A未提交的更新结果。 2. 提交:只允许事务取已经提交的数据,解决了脏的问题。例如,用户A正在执行事务并更新某行数据,此时用户B不会取到用户A的未提交更新结果。 3. 可重复:保证同一事务的多个查询操作返回的结果一致,即使其他事务已经修改了相同的数据。例如,用户A在一个事务中执行了一个查询操作,并且返回了结果,然后用户B修改了相同的数据,但是用户A再次执行相同的查询操作时,返回的结果应该和之前相同。 4. 串行化:最高的隔离级别,保证任何时候只有一个事务能够访问某个数据项,避免了并发操作可能导致的(phantom read)问题。例如,用户A正在执行一个事务操作,并且开始了一个长时间的查询操作,此时用户B不能修改关于此查询的数据。 需要注意的是,随着隔离级别的提升,对并发性的支持减弱,因此在实际应用中需要根据具体情况选择合适的事务隔离级别。 ### 回答3: 数据库事务的四种级别分别是:未提交(Read Uncommitted)、已提交(Read Committed)、可重复(Repeatable Read)和串行化(Serializable)。 1. 未提交(Read Uncommitted):事务最低级别,一个事务可以取另一个事务未提交的数据。例如,事务A对某条数据进行修改,尚未提交,同时事务B取了这条数据,这时事务B到了A未提交的数据。 2. 已提交(Read Committed):事务在取数据时,只能取已经提交的数据,这样可以避免脏。例如,事务A对某条数据进行修改并提交,事务B在此之后取该数据,此时事务B取的是A已经提交的数据。 3. 可重复(Repeatable Read):在一个事务执行期间,多次取同一数据结果保持一致,不受其他事务的影响。例如,事务A在某个时间点取了某个数据,然后事务B在此之后对该数据进行了修改并提交,但是事务A再次取该数据时,依旧能够取到修改之前的数据结果。 4. 串行化(Serializable):事务按照串行化的方式执行,一个事务执行时,其他事务无法对其访问的数据进行修改。例如,事务A对某个数据进行了取和修改操作,此时事务B要对同一数据进行修改,则事务B需要等待事务A执行完毕并释放该数据。 这四种级别各自适用于不同的场景,选择合适的级别可以在保证数据的一致性的同时,提高并发性能。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值