繁体   English   中英

与 JPA 同步并发批量更新

[英]Synchronize concurrent batch updates with JPA

此示例经过修改和简化,但类似于我在尝试修复遗留代码时遇到的真实问题。

我有一个 MSSQL CAR表(其中id是主键)

ID 制作 地位
1个 宝马 水洗
2个 宝马 肮脏的
3个 宝马 肮脏的
4个 福特 肮脏的
... ... ...

和一个/washNextCars端点。

@PatchMapping("/washNextCars")
public ResponseEntity<List<Car>> washNextCars(
      @RequestBody WashCarBody body,
      @RequestParam String status,
      @RequestParam String make,
      @RequestParam Integer limit) {
  ...
}

以下请求将接下来的10辆车的 state 从DIRTY更改为WASHED

PATCH /washNextCars?status=DIRTY&make=BMW&limit=10
{
    "status": "WASHED"
}

这是粗略的业务逻辑:

  @Transactional
  public List<Car> washNextCars(WashCarDTO dto) {

    // SELECT TOP ? * FROM CAR WHERE make=? AND status='DIRTY' ORDER BY id ASC 
    List<Car> nextCars = carRepository.findNextCars(limit, make, status);

    // do some complex validation on every car if it can be washed, therefore can't do everything in one single UPDATE query

    cars.forEach(car -> {
      car.setStatus("WASHED");
    });
    carRepository.saveAll(nextCars);
  }

此端点在顺序调用时工作正常,但在并行调用时,它会尝试同时对同一组汽车执行更新,而不是下一批汽车。

问题:

  • 如何在第一个调用完成之前同步调用?
    • 请注意,这必须在数据库级别实现,因为 API 被部署为多个副本
  • 我发现了以下选项:
    • @Transactional(isolation = READ_UNCOMMITED)
      • 这需要在执行业务逻辑中的任何其他语句之前将汽车更新为WASHED ,对吗?
    • @Lock(PESSIMISTIC_WRITE_LOCK) - 没有提供预期的效果
  • 实现这一目标的正确方法是什么?

尝试使用 UPDLOCK:

SELECT ... FROM tab1 WITH (UPDLOCK) WHERE ...

类似于

SELECT 更新

在 Oracle。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM