我在扩展 CrudRepository 的接口中有这个方法:
@Lock(LockModeType.PESSIMISTIC_WRITE)
Voucher findTop1ByUsedFalseAndProductOrderByIdAsc(Product product);
Run Code Online (Sandbox Code Playgroud)
而这个组件:
@Component
@Transactional
public class VoucherFetchComponent {
@Autowired
private VoucherRepository voucherRepository;
public Voucher fetch(Product product) {
Voucher voucher=voucherRepository.findTop1ByUsedFalseAndProductOrderByIdAsc(product);
if(voucher==null)
return null;
voucher.setUsed(true);
voucherRepository.save(voucher);
return voucher;
}
}
Run Code Online (Sandbox Code Playgroud)
问题是同时执行 fetch() 方法。(假设我的数据库中只剩下 1 张优惠券)
我的期望:
1- 服务 A 和 B 调用 VoucherFetchComponent 的 fetch() 方法
2- 服务 A(或 B)锁定行,更新其中一个字段并返回
3- 其他服务现在可以访问被锁定的行。但是现在查询与给定的条件不匹配(used=false),因此它返回 null。
我得到的
1 和 2 就像上面一样
3- 其他服务返回具有参数(used=false)但之前已更新的旧对象!