database - 使用 REPEATABLE READ 保证特定值的唯一性

标签 database spring postgresql isolation-level

我们有一个简单的表格:

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())
}

而且我想保证恰好存在一个具有特定高度的人。

  1. REPEATABLE_READ 能保证吗?
  2. 我的代码(伪代码)是否正确以满足该条件?

最佳答案

理论说唯一能够绝对保证重新的隔离级别。数据完整性(wrt 声明的规则)是可序列化的。

使用 REPEATABLE READ,从理论上讲,您仍然面临着两个事务试图插入同一行以及以下事件序列让其通过的风险:

T1检查行是否存在,行不存在
T2 检查行是否存在,行不存在
T1 插入,可能重复该行的存在性检查(仍然不存在)
T2 插入,可能会重复该行的存在性检查(仍然“不存在”,因为 T1 尚未提交,因此其新插入的数据对 T2 不可见)。
T1 提交
T2 提交

REPEATABLE READ,顾名思义,只提供关于现有行的保证(即如果发现一行存在,它不会被改变由其他事务处理,然后读取变为“可重复”)。

关于database - 使用 REPEATABLE READ 保证特定值的唯一性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50564493/

相关文章:

sql - 如何在达到阈值后运行 SUM "reset"?

python - 我如何做大于/小于使用 MongoDB?

database - DB2 SQLCODE=-805,SQLSTATE=51002,SQLERRMC=NULLID.SYSLH203 0X5359534C564C3031

php - Laravel 在 php artisan make :auth 之后进行 php artisan 迁移失败

java - 请求方法 'GET' 不支持 Spring MVC

java - 条件注释上的 CacheEvict - Spring Caching

java - Spring Bean 到底是什么?

php - 无法将数据从表单插入数据库

postgresql - Postgres - 一旦行中的列不为空,如何停止更新行

java - Postgresql 枚举在 springboot 1.5->2.0 迁移期间中断