Spring Data JPA 解决秒杀系统中减库存操作

之前更新库存逻辑是先拿到 Goods 对象,然后将库存设置为当前库存减1,然后调用 GoodsRepository.save() 方法保存更新后的对象。这个处理逻辑会导致超售。

先上部分控制逻辑代码:

Goods goods = goodsRepository.findById(id).get();
goods.setNumber(goods.getNumber() - 1);
if (goods.getNumber() <= 0) {throw new SeckillException(ResultEnum.END);
}
goodsRepository.save(goods);

 

新的方法是使用 @Transactional 注解管理事务和 @Query 注解自定义查询方法。

首先在 GoodsRepository 接口中定义一个减库存方法:

    @Transactional
    @Modifying(clearAutomatically = true)
    @Query(value = "update Goods set number = number -1 where id=?1 and number>0")
    int reduceStock(Integer id);

要注意的几点是:

1.@Transactional 注解要使用 org.springframework.transaction.annotation.Transactional 包下的。( javax.transaction.Transactional 包下的一般是JAVA EE项目使用)

2.@Query 注解中 nativeQuery 项默认为 false,代表使用 JPQL 语句查询。nativeQuery = true 代表使用原生 SQL 语句查询。 下面两段代码功能一致:

@Query(value = "update Goods set number = number -1 where id=?1 and number>0")
@Query(value = "update goods set number = number -1 where id=?1 and number>0",nativeQuery = true)

 

然后逻辑代码可以更新为:

Goods goods = goodsRepository.findById(id).get();
int state = reduceStock(id);
if(state != 0){
  //保存订单
}

 

更新代码后测试未出现超售现象。

 

 

参考链接:

https://www.ibm.com/developerworks/cn/java/j-master-spring-transactional-use/index.html

https://www.oracle.com/technetwork/articles/vasiliev-jpql-085775-zhs.html?printOnly=1

https://zhuanlan.zhihu.com/p/29611306

https://blog.csdn.net/zt15732625878/article/details/78378995

转载于:https://www.cnblogs.com/1x11/p/10873272.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值