这个例子经过了修改和简化,但类似于我试图修复的遗留代码中的一个实际问题。
我有一个MSSQL CAR
表(其中id
是主键)
| 身份证|制造|地位|
| - ------|- ------|- ------|
| 1个|宝马|清洗|
| 第二章|宝马|肮脏|
| 三个|宝马|肮脏|
| 四个|福特|肮脏|
| ...|...|...|
和/washNextCars
端点。
@PatchMapping("/washNextCars")
public ResponseEntity<List<Car>> washNextCars(
@RequestBody WashCarBody body,
@RequestParam String status,
@RequestParam String make,
@RequestParam Integer limit) {
...
}
以下请求将下一个10
车厢的状态从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)
- 这需要在执行业务逻辑中的任何其他语句之前将cars更新为
WASHED
,对吗? @Lock(PESSIMISTIC_WRITE_LOCK)
-未提供预期效果- 实现这一目标的正确途径是什么?
1条答案
按热度按时间r55awzrz1#
尝试使用UPDLOCK:
类似于
选择更新
在甲骨文。