java - Spring Boot 中的 Hibernate JPA/CrudRepository 实体锁定
问题描述
我正在尝试开发的 REST 应用程序存在以下问题: 在我的一个服务类中,我有一种方法可以从数据库中删除对象,同时在该资源不存在时通知用户,类似于以下内容:
@Transactional
public class MyEntityService {
@Autowired
private MyEntityrepository repo
public void delete(String name) {
MyEntity e = repo.findByName(name)
.orElseThrow(() -> new ResourceNotFoundException(name));
repo.delete(e);
}
}
我有什么方便的方法可以确保对 delete 方法的调用不与目标相同的实体重叠?我考虑使用 EntityManagers 锁定方法(https://www.objectdb.com/api/java/jpa/EntityManager/lock_Object_LockModeType),如下所示:
MyEntity e = repo.findByName(name)
.orElseThrow(() -> new ResourceNotFoundException(name));
try {
em.lock(e, LockModeType.PESSIMISTIC_WRITE)
} catch ( PessimisticLockException e) {
//Handle somehow
}
repo.delete(e);
但我不确定这是否是正确的方法,或者如果我尝试删除将其删除级联到锁定实体的父实体会发生什么。
解决方案
有两种方法可以解决这个问题:悲观锁定和乐观锁定。
我不会在应用程序级别使用悲观锁定,而是使用数据库隔离级别处理数据对多个事务的可见性。我在这里假设您使用的是RDMS。了解您的数据库的并发控制机制,并根据您的应用程序需求选择合适的隔离级别。PostgreSQL文档是一个很好的资源。
然后您可以使用乐观锁定来处理丢失更新问题。我建议您阅读有关该主题的出色资源。
推荐阅读
- c# - 自动生成的 WCF 代码具有布尔值,具有“指定”附加字段
- r - 当用户将鼠标悬停在闪亮仪表板的标题部分时停用颜色变化
- angular - 离子电容器 CameraPreview - 相机始终位于顶部。不可能有 HTML 覆盖
- shopify - 在 shopify 主题中添加“新”、“销售”等产品标签
- flutter - 如何在 Flutter 上使用 audio_service 使用本地化的 MediaItem 标题和专辑
- html - Flexbox "flex: 1" 没有正确居中并且 "flex-grow" 推高其他内容
- python - 从 keras fashion_mnist 加载数据时出现 URL 错误 403
- java - 发送前修改springframework.ws.WebServiceMessage xml
- python - 如何从模型传递上下文并在 odoo 中查看?
- oauth - 授权代码流 - 来自多个选项卡的并发请求