mysql乐观锁实现思路

4.1 mysql 乐观锁解决超卖问题 - 图1

go使用乐观锁实现分布式锁

  1. func (*InventoryServer) Sell(ctx context.Context, req *proto.SellInfo) (*emptypb.Empty, error) {
  2. var inv model.Inventory
  3. var details []model.GoodsDetail
  4. //一个订单可以购买多个商品
  5. //req.GoodsInfo 多件商品 同时减库存
  6. for _, goodInfo := range req.GoodsInfo {
  7. details = append(details, model.GoodsDetail{
  8. Goods: goodInfo.GoodsId,
  9. Num: goodInfo.Num,
  10. })
  11. //如果没有更新成功一直重试
  12. for true {
  13. if result := global.DB.Where(&model.Inventory{Goods: goodInfo.GoodsId}).First(&inv); result.RowsAffected == 0 {
  14. return nil, status.Errorf(codes.InvalidArgument, "没有库存信息")
  15. }
  16. //判断库存是否充足
  17. if inv.Stocks < goodInfo.Num {
  18. return nil, status.Errorf(codes.ResourceExhausted, "库存不足")
  19. }
  20. //扣减, 会出现数据不一致的问题 - 锁,分布式锁
  21. tx := global.DB.Select("stocks", "version").Where("goods = ?", goodInfo.GoodsId).Where("version = ?", inv.Version).Updates(model.Inventory{Stocks: inv.Stocks - 1, Version: inv.Version + 1})
  22. if tx.RowsAffected == 1 {
  23. break
  24. }
  25. }
  26. }
  27. return &emptypb.Empty{}, nil
  28. }