首页 > 解决方案 > 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);

但我不确定这是否是正确的方法,或者如果我尝试删除将其删除级联到锁定实体的父实体会发生什么。

标签: javaspringhibernatespring-bootjpa

解决方案


有两种方法可以解决这个问题:悲观锁定和乐观锁定

我不会在应用程序级别使用悲观锁定,而是使用数据库隔离级别处理数据对多个事务的可见性。我在这里假设您使用的是RDMS。了解您的数据库的并发控制机制,并根据您的应用程序需求选择合适的隔离级别。PostgreSQL文档是一个很好的资源。

然后您可以使用乐观锁定来处理丢失更新问题。我建议您阅读有关主题的出色资源。


推荐阅读