我们有一个简单的表格:
Human:
+------+
|Height|
+------+
| |
+------+
我有一个添加人的方法:
@AutoWired
HumanRepository humanRepo; // JpaRepository
@Transactional(isolationLevel = REPEATABLE_READ)
void addHuman(int height){
if(humanRepo.existsByHeight(height){
throw new HumanWithSuchHeightExists();
}
humanRepo.save(Human.builder().height(height).build())
}
而且我想保证恰好存在一个具有特定高度的人。
REPEATABLE_READ
能保证吗?- 我的代码(伪代码)是否正确以满足该条件?
最佳答案
理论说唯一能够绝对保证重新的隔离级别。数据完整性(wrt 声明的规则)是可序列化的。
使用 REPEATABLE READ,从理论上讲,您仍然面临着两个事务试图插入同一行以及以下事件序列让其通过的风险:
T1检查行是否存在,行不存在
T2 检查行是否存在,行不存在
T1 插入,可能重复该行的存在性检查(仍然不存在)
T2 插入,可能会重复该行的存在性检查(仍然“不存在”,因为 T1 尚未提交,因此其新插入的数据对 T2 不可见)。
T1 提交
T2 提交
REPEATABLE READ,顾名思义,只提供关于现有行的保证(即如果发现一行存在,它不会被改变由其他事务处理,然后读取变为“可重复”)。
关于database - 使用 REPEATABLE READ 保证特定值的唯一性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50564493/