hibernate - 更新同一实体时的 Spring Boot 竞争条件
问题描述
对于spring boot,我知道如果我有一个功能说,为了减少用户的余额,我们可以在服务方法中使用@Transactional注释,如下所示:
@Transactional
public void reduceBalance(long userId, BigDecimal usage) {
...
}
但我的问题不是指将控制置于特定功能,我想知道如下:
public void updateAge(long userId, int newAge) {
User theUser = userRepository.findById(userId).orElse(null); // Line A-1
theUser.setAge(newAge); // Line A-2
userRepository.save(theUser); // Line A-3
}
public void updateName(long userId, String newName) {
User theUser = userRepository.findById(userId).orElse(null); // Line B-1
theUser.setName(newName); // Line B-2
userRepository.save(theUser); // Line B-3
}
假设如果有 2 个请求同时进入,则 A-1 和 B-1 行同时执行,然后是 A-2 和 B-2,然后是 A-3 和 B-3。
B-3 会覆盖 A-2 的更改吗?如果是,这是否意味着我们应该在几乎每个服务中都添加 @Transactional 注释,或者实际上是否有更好的设计?
解决方案
强烈建议在每个服务中使用@Transaction,但如果您想通过不同的方式进行管理,其他方式是使用@Version 注释
Specifies the version field or property of an entity class that
serves as its optimistic lock value. The version is used to ensure
integrity when performing the merge operation and for optimistic
concurrency control.
推荐阅读
- javascript - 同时将音频和麦克风流录制为不同的 MediaRecorder 轨道
- angular - 如何从结构指令呈现字符串?
- binding - SwiftUI – 尝试将操作表可见性绑定到已发布的 var 属性
- flutter - 如何使用提供程序获取数据?
- c - 程序不循环
- bash - 修改 Mac OS 终端颜色不起作用。可能是由于对 anaconda 的 bash_profile 修改?
- java - 如何使用 XMLUnit DiffBuilder 检测属性和元素列表的差异
- c# - 在 SQL 存储过程中使用用户定义的表 - 无效的数据类型
- sql - 使用 OPENJson 向表中插入数据
- embedding - 谷歌colab中gpu中的cuda内存不足问题