对象图和READ_COMMITTED事务隔离

时间:2011-03-11 15:15:46

标签: database-design

CAVEAT :几年前我遇到了这个问题。我忘记了我试图解决的实际问题,所以我用一个涉及链表的理论问题代替了它。


我一直在尝试使用READ_COMMITTED事务隔离级别超过一年,而且由于缺乏经验而导致的错误非常感到沮丧。如果你们能帮助我了解我在这里缺少的东西,我将不胜感激。

我实现的几乎所有应用程序逻辑都不能用单个SQL查询来表达。也就是说,我几乎总是不得不走对象图。不可避免地,我在同一个交易中遇到了不一致的状态。例如,假设您在数据库中存储单链接列表,并且您想要确定列表是否包含循环(在下面更详细地描述)。我无法想到在READ_COMMITTED下执行此操作的任何方法,因为当我走图表时,可以从我脚下更新出站引用。我只能看到READ_COMMITTED工作用于可以使用单个SQL语句表示的查询。

  • 数据库架构为Node[id, name, next_id]
  • 最初,数据库包含:A -> B -> C -> A

    1. 主题1读取:A -> BB -> C
    2. 线程2将数据库更新为:D -> B -> C -> D
    3. 主题1读取:C -> D
    4. 虽然应该检测到一个循环,但是线程1没有检测到循环。从线程1的角度来看,它读取:A -> B -> C -> D但它应该检测到以下循环之一:

A -> B -> C -> AD -> B -> C -> D

1 个答案:

答案 0 :(得分:0)

回答Michal Bergmann的问候:http://groups.google.com/group/h2-database/browse_frm/thread/8f253177e2b6c543?tvc=1

  

READ_COMMITTED_SNAPSHOT隔离级别可以帮助您解决问题   与并发操作。它允许执行多个查询   不受其他同时交易的影响。

     

你也可以

     
      
  • 首先将数据复制到临时表
  •   
  • 锁定表并阻止更新
  •   
  • 监视表以进行更改(使用触发器)以及是否更改   在循环检测期间,您的结果可能无效,那么您可以   扔掉它并重复循环检测。
  •   
  • 使用应用程序逻辑推迟任何更改,直到循环检测为止   完成
  •   
     

使用READ_COMMITTED_SNAPSHOT隔离级别可能是最好的   解决方案,如果数据库支持它。它的开销很低,但没有   阻止并发事务。