乐观锁定和Spring数据JPA

lbsnaicq  于 2023-01-05  发布在  Spring
关注(0)|答案(1)|浏览(163)

我在我的项目中使用Spring Data JPA,并计划采用乐观锁机制,但我还没有看到Spring Data JPA可以与乐观锁一起工作。
我有一个具体的例子,据我所知,这是一种串行化隔离无法覆盖多个事务被读取和更新的情况。
The concrete example
我使用的是Cockroach Database,它只支持SerializableIsolation。下面是我习惯与数据库交互的两个函数:

@Getter
@Setter
@NoArgsConstructor
@Entity(name = "account")
@DynamicUpdate
@ToString
public class AccountEntity {

  @Id
  @Column(columnDefinition = "UUID")
  private UUID id;
  
  @NotNull
  @Column(name = "status")
  @Enumerated(EnumType.STRING)
  private Status status;
  
  @Version
  private Long version;
  
}
  • 账户主体 *
public AccountDto getAccount(UUID id) {
    AccountEntity entity = this.accountRepository.findById(id).orElseThrow();
    return new AccountDto(entity.getId(), entity.getStatus());
  }
  • 获取API*
@Transactional
  public AccountDto updateAccount(UUID id, @Valid Long sleep,
      @Valid AccountUpdateDto accountUpdateDto) {
    log.info("Start updating status [{}] for the account {}.", accountUpdateDto.getStatus(), id);

    AccountEntity entity = this.accountRepository.findById(id).orElseThrow();

    entity.setStatus(accountUpdateDto.getStatus());
    
    AccountDto accountDto = new AccountDto(id, accountUpdateDto.getStatus());
    log.info("Finish updating status [{}] for the account {}.", 
    accountUpdateDto.getStatus(), id);
    return accountDto;
  }
  • 放置API*

在图片中,我期望抛出一个OptimisticLockException,但是当用户1更新账号时,它仍然可以正常更新账号,因为在updateAccount方法中,找到的是最新版本的账号,不可能出现OptimisticLockException
那么在什么情况下它会抛出乐观锁定异常呢?

zbwhf8kr

zbwhf8kr1#

乐观锁定在事务开始时看到某个数据的版本A,后来看到该数据的不同版本A“时生效。
但是正如你所说的,Cockroach DB使用事务隔离级别serializable,这意味着对于每个事务来说,所有的事情看起来都像没有其他事务在同时运行,因此上面的场景不可能发生。
切换到具有更宽松事务隔离级别的数据库,您应该能够看到OptimisticLockingException

相关问题