不可重复读

有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top

全网最细面试题手册,支持艾宾浩斯记忆法。这是一份最全面、最详细、最高质量的 java 面试题,不建议你死记硬背,只要每天复习一遍,有个大概印象就行了。https://store.amazingmemo.com/chapterDetail/1685324709017001

不可重复读

1. 什么是不可重复读?

不可重复读(Non-repeatable Read)指的是在同一个事务中,多次读取同一数据集合时,由于其他并发事务的提交,后续读取的结果与前面的不一致。这是因为其他事务在这两次读取之间修改了数据。

2. 为什么需要避免不可重复读?

避免不可重复读是为了保持事务的一致性视图。在商业逻辑中,经常需要对一组数据进行多次读取,并假设在事务期间数据是不变的。如果其他事务能够修改这些数据,那么这个假设就不成立了,可能会导致错误的业务决策。

3. 不可重复读的实现原理?

不可重复读主要与数据库的隔离级别有关。在某些隔离级别(如可重复读或串行化)下,数据库使用锁或多版本并发控制(MVCC)机制来保证同一事务中的查询能够得到相同的数据结果。

实现机制:

  • 锁定:在一些数据库系统中,事务在读取数据时会对其加锁,防止其他事务进行写入。

  • MVCC:在其他系统(如 MySQL 的 InnoDB 存储引擎)中,事务不会直接读取实际数据,而是读取数据的快照,即使其他事务提交了更新,也不会影响这个事务的数据视图。

4. 不可重复读的使用示例

以下是不可重复读的一个 SQL 示例:

-- 事务 1
START TRANSACTION;
SELECT balance FROM accounts WHERE user_id = 1; -- 假设返回余额是 100

-- 事务 2
START TRANSACTION;
UPDATE accounts SET balance = balance - 50 WHERE user_id = 1;
COMMIT;

-- 事务 1
SELECT balance FROM accounts WHERE user_id = 1; -- 如果隔离级别不够,现在返回的余额可能是 50
COMMIT;

在此示例中,如果事务 1 的隔离级别未能阻止不可重复读,它将在第二次查询时看到不同的余额。

5. 不可重复读的优点

与脏读类似,不可重复读通常被视为负面现象,但在一些需要高并发的应用场景中,允许不可重复读可能会提升性能。

6. 不可重复读的缺点

  • 数据不一致:事务中的后续操作可能基于过时的数据,导致不正确的结果。

  • 逻辑错误:业务逻辑可能因为读取到的数据变化而出现错误。

7. 不可重复读的使用注意事项

  • 隔离级别:应该选择适当的隔离级别(如可重复读或串行化)来防止不可重复读。

  • 业务逻辑:业务逻辑应当设计成能够容忍或检测数据在事务中的变化。

  • 性能权衡:在一些场景下,为了提升性能,可能会有意选择较低的隔离级别,这时需要确保业务逻辑的正确性不会受到影响。

8. 总结

不可重复读是一个事务在执行期间可能遇到的问题,尤其是在并发环境中。通过采用合适的事务隔离级别,可以有效地避免不可重复读,确保事务的一致性和可靠性。然而,在需要高并发处理的系统中,可能需要在数据一致性和系统性能之

间做出权衡。

最后更新于