一尘不染

使用Spring Data JPA查找实体时如何启用LockModeType.PESSIMISTIC_WRITE?

spring

我该如何实现与以下代码等效的功能:

tx.begin();
Widget w = em.find(Widget.class, 1L, LockModeType.PESSIMISTIC_WRITE);
w.decrementBy(4);
em.flush();
tx.commit();

…但是使用Spring和Spring-Data-JPA批注?

我现有代码的基础是:

@Service
@Transactional(readOnly = true)
public class WidgetServiceImpl implements WidgetService
{
  /** The spring-data widget repository which extends CrudRepository<Widget, Long>. */
  @Autowired
  private WidgetRepository repo;

  @Transactional(readOnly = false)
  public void updateWidgetStock(Long id, int count)
  {
    Widget w = this.repo.findOne(id);
    w.decrementBy(4);
    this.repo.save(w);
  }
}

但是我不知道如何指定该updateWidgetStock方法中的所有操作都应使用悲观锁集。

有一个Spring Data JPA批注org.springframework.data.jpa.repository.Lock,允许你设置LockModeType,但我不知道将其放在updateWidgetStock方法上是否有效。听起来更像是的注解WidgetRepository,因为Javadoc说:

org.springframework.data.jpa.repository @Target(value=METHOD) @Retention(value=RUNTIME) @Documented public @interface Lock Annotation used to specify the LockModeType to be used when executing the query. It will be evaluated when using Query on a query method or if you derive the query from the method name.

…因此似乎无济于事。

如何使我的updateWidgetStock()方法通过LockModeType.PESSIMISTIC_WRITEset 执行?


阅读 1116

收藏
2020-04-18

共1个答案

一尘不染

@Lock从Spring Data JPA 1.6版开始,CRUD方法就支持该功能(实际上,已经有了一个里程碑)。有关更多详细信息。

使用该版本,你只需声明以下内容:

interface WidgetRepository extends Repository<Widget, Long> {

  @Lock(LockModeType.PESSIMISTIC_WRITE)
  Widget findOne(Long id);
}

这将导致后备存储库代理的CRUD实现部分将已配置的应用LockModeType到上的find(…)调用EntityManager

2020-04-18