【问题标题】:Dirty read or phantom read in multiple insert transaction?多个插入事务中的脏读或幻读?
【发布时间】:2012-09-18 21:48:57
【问题描述】:

我了解在isolation levels 的维基百科页面上给出的“脏读”和“幻读”示例。但是,我不确定如何对以下情况进行分类,以及应用什么隔离级别或不同的策略来避免这种情况。

  1. 事务 1:在表 A 中插入行
  2. 事务 2:选择表 A 中的行
  3. 事务 2:根据之前读取的内容选择表 B 中的行
  4. 事务 2:提交
  5. 事务 1:在表 B 中插入行
  6. 事务 1:提交

问题是事务 2 在 T1 在两个表中完成写入之前选择了 B 中的某些内容。第 3 步中的选择可能需要选择 5 中插入的行才能正确。这是脏读,幻读还是两者都不是。 READ_COMMITTED 隔离级别是否足以避免问题?据我了解,使用 READ_COMMITTED T2 不应该读取 T1 在此时插入的新行。

【问题讨论】:

  • 您在第 4 步中提交了什么 - 我没有看到事务 2 修改任何数据?
  • @Kaivosukeltaja 因为它只是 SELECTS,所以在 T2 上没有实际提交。我只是添加它以表明该事务没有更多操作。我将编辑问题以使其更清楚。

标签: mysql transactions


【解决方案1】:

这是一个脏读。在READ_COMMITTED 隔离级别中,第 2 步中的查询不会返回您在第 1 步中插入但尚未提交的行,从而防止尝试访问尚未插入的数据失败。

幻读意味着您在事务 2 中执行了两次相同查询并获得了不同的结果集。

【讨论】:

  • 只是为了确保:只是 T2 应该有隔离级别 READ_COMMITTED? T1的隔离级别是否相关?在某些地方,文档说 “此级别禁止事务读取其中包含未提交更改的行”,这表明读取事务应该具有 READ_COMMITTED,而在其他地方,文档说 “在这种隔离级别,DBMS 实现会保留写锁”,这表明写事务应该是具有 READ_COMMITTED 的事务。
  • @CristianVrabie:应该为 T2 指定 READ_COMMITTED,因为它会影响读取时的锁定行为。示例见此链接:herongyang.com/MySQL/… 另请注意,InnoDB 中的默认事务隔离级别是 REPEATABLE READ,它甚至比 READ COMMITTED 更加隔离。
猜你喜欢
  • 2014-10-06
  • 1970-01-01
  • 2018-12-13
  • 2019-07-06
  • 2019-04-16
  • 1970-01-01
  • 2018-10-02
  • 2019-06-16
  • 1970-01-01
相关资源
最近更新 更多