【发布时间】: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