gpt4 book ai didi

java - Spring data PESSIMISTIC_WRITE 返回旧的 DB 值

转载 作者:行者123 更新时间:2023-12-05 00:55:18 26 4
gpt4 key购买 nike

我的界面中有这个方法,它扩展了 CrudRepository:

@Lock(LockModeType.PESSIMISTIC_WRITE)
Voucher findTop1ByUsedFalseAndProductOrderByIdAsc(Product product);

而这个组件:
@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;
}
}

问题是同时执行 fetch() 方法。 (假设我的数据库中只剩下一张优惠券)

我的期望:

1- 服务 A 和 B 调用 VoucherFetchComponent 的 fetch() 方法

2- 服务 A(或 B)锁定行,更新其中一个字段并返回

3-其他服务现在可以访问被锁定的行。但是现在查询与给定的条件不匹配(used=false),所以它返回 null。

我得到了什么

1和2就像上面一样

3- 其他服务返回具有参数 (used=false) 但之前已更新的旧对象!

最佳答案

如果您仔细查看 @Lock 的 javadoc,它会指出:

Annotation used to specify the LockModeType to be used when executing the query.



所以锁仅在查询执行期间处于 Activity 状态..查询完成后..锁被释放。正如您所期望的那样,它在整个事务期间并不活跃。

我建议使用标准锁定机制:

凭证存储库
public void lock(Voucher voucher, LockModeType lockType){

entityManager.lock(voucher, lockType);

VoucherFetchComponent
public Voucher fetch(Product product) {
Voucher voucher=voucherRepository.findTop1ByUsedFalseAndProductOrderByIdAsc(product);
if(voucher==null)
return null;
voucherRepository.lock(voucher, LockModeType.PESSIMISTIC_WRITE);
voucher.setUsed(true);
voucherRepository.save(voucher);
return voucher;
}

事务完成后,锁将被释放。

关于java - Spring data PESSIMISTIC_WRITE 返回旧的 DB 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42530115/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com