【问题标题】:Transaction isolation ANSI REPEATABLE_READ in DB2 not locking rows as expectedDB2 中的事务隔离 ANSI REPEATABLE_READ 未按预期锁定行
【发布时间】:2018-06-15 13:35:54
【问题描述】:

我无法解释 DB2 隔离级别的情况。

我有一个隔离级别为 REPEATABLE_READ 的事务,它在 DB2 中对应于 READ_STABILITY。

我对 DB2 S-、U-和 X-锁有基本的了解。

当我并行执行以下 Spring 事务时,可能会导致死锁(来自 DB2 的错误是 FILE IN USE):

@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRES_NEW)
public long getNext(int x) {
    final Stuff stuff = entityManager
            .createQuery("from Stuff where type = :type", Stuff.class)
            .setParameter("cardType", cardType)
            .getSingleResult();

    stuff.setData(stuff.getData() + x);
    return stuff.getData()+1;
}

我希望 REPEATABLE_READ 隔离会在返回的行上设置一个 DB2 U 锁,以便并行事务排队。

相反,为了让它工作,我需要添加一个悲观的写锁:

@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRES_NEW)
public long getNext(int x) {
    final Stuff stuff = entityManager
            .createQuery("from Stuff where type = :type", Stuff.class)
            .setParameter("cardType", cardType)
            .setLockMode(LockModeType.PESSIMISTIC_WRITE)
            .getSingleResult();


    stuff.setData(stuff.getData() + x);
    return stuff.getData()+1;
}

上述查询生成正确的锁定 SQL 并且事务工作没有死锁:

select * from .... for update with rs;

问题是,当我还需要手动锁定时,为什么还要使用 REPEATABLE_READ 呢?我的理解是 REPEATABLE_READ 必须自己处理必要的行锁定以确保可重复读取。

【问题讨论】:

  • 您的 Db2 服务器操作系统是什么? (Z/OS、i 系列、Linux/Unix/Windows)和您的 Db2 服务器版本?
  • 它是 iSeries 版本 7 Release2 (V7R2)。
  • 可重复阅读听起来没有人可以在您阅读时更改表格。听起来 IBM 也只是锁定了表。

标签: spring-transactions db2-400 isolation-level pessimistic-locking


【解决方案1】:

Db2 for i 支持可重复读取 (RR) 和读取稳定性 (RS)。

Repeatable Read

在 SQL 2003 Core 标准中,Repeatable Read 称为 Serializable。
Db2® for i 支持通过 COMMIT(*RR) 进行可重复读取。通过锁定包含任何已读取或更新行的表来支持可重复读取隔离级别。

可重复读取是最高级别的隔离。

如果您只想锁定您触摸的行,我认为您需要读取稳定性(RS)。这是一个下降。不同的是 RS 允许 phantom reads

幻影。工作单元 UW1 读取满足某个搜索条件的 n 行集合。然后工作单元 UW2 插入满足搜索条件的一个或多个行。 UW1然后以相同的搜索条件重复初始读取,并获得原始行加上插入的行。

【讨论】:

  • 我使用的是上面Spring相关注释中指定的RS,但是查询似乎并没有真正锁定第一个select语句中返回的行。这就是为什么我在同时运行事务时仍然会遇到死锁问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-18
  • 2015-08-26
相关资源
最近更新 更多