久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長(zhǎng)資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      詳解Go庫(kù)存扣減如何實(shí)現(xiàn)的(多種方法)

      本文由golang教程欄目給大家介紹關(guān)于Go 庫(kù)存扣減的幾種實(shí)現(xiàn)方法,希望對(duì)需要的朋友有所幫助!

      Go 庫(kù)存扣減的幾種實(shí)現(xiàn)方法

      這里使用了 grpc、proto、gorm、zap、go-redis、go-redsync 等 package

      Go Mutex 實(shí)現(xiàn)
      var m sync.Mutexfunc (*InventoryServer) LockSell(ctx context.Context, req *proto.SellInfo) (*emptypb.Empty, error) {     tx := global.DB.Begin()     m.Lock()      for _, good := range req.GoodsInfo {         var i model.Inventory        if result := global.DB.Where(&model.Inventory{Goods: good.GoodsId}).First(&i);               result.RowsAffected == 0 {             tx.Rollback() // 回滾             return nil, status.Errorf(codes.InvalidArgument, "未找到此商品的庫(kù)存信息。")         }         if i.Stocks < good.Num {             tx.Rollback()              return nil, status.Errorf(codes.ResourceExhausted, "此商品的庫(kù)存不足")         }         i.Stocks -= good.Num         tx.Save(&i)     }     tx.Commit()     m.Unlock()     return &emptypb.Empty{}, nil}
      MySQL 悲觀鎖實(shí)現(xiàn)
      func (*InventoryServer) ForUpdateSell(ctx context.Context, req *proto.SellInfo) (*emptypb.Empty, error) {     tx := global.DB.Begin()     for _, good := range req.GoodsInfo {         var i model.Inventory        if result := tx.Clauses(clause.Locking{             Strength: "UPDATE",         }).Where(&model.Inventory{Goods: good.GoodsId}).First(&i);             result.RowsAffected == 0 {             tx.Rollback()             return nil, status.Errorf(codes.InvalidArgument, "未找到此商品的庫(kù)存信息。")         }         if i.Stocks < good.Num {             tx.Rollback()             return nil, status.Errorf(codes.ResourceExhausted, "此商品的庫(kù)存不足")         }          i.Stocks -= good.Num         tx.Save(&i)     }      tx.Commit()     return &emptypb.Empty{}, nil}
      MySQL 樂(lè)觀鎖實(shí)現(xiàn)
      func (*InventoryServer) VersionSell(ctx context.Context, req *proto.SellInfo) (*emptypb.Empty, error) {     tx := global.DB.Begin()     for _, good := range req.GoodsInfo {         var i model.Inventory        for { // 并發(fā)請(qǐng)求相同條件比較多,防止放棄掉一些請(qǐng)求             if result := global.DB.Where(&model.Inventory{Goods: good.GoodsId}).First(&i);                 result.RowsAffected == 0 {                  tx.Rollback()                 return nil, status.Errorf(codes.InvalidArgument, "未找到此商品的庫(kù)存信息.")             }             if i.Stocks < good.Num {                 tx.Rollback() // 回滾                 return nil, status.Errorf(codes.ResourceExhausted, "此商品的庫(kù)存不足")             }             i.Stocks -= good.Num             version := i.Version + 1             if result := tx.Model(&model.Inventory{}).                 Select("Stocks", "Version").                 Where("goods = ? and version= ?", good.GoodsId, i.Version).                 Updates(model.Inventory{Stocks: i.Stocks, Version: version});                 result.RowsAffected == 0 {                                  zap.S().Info("庫(kù)存扣減失敗!")             } else {                 break             }         }     }     tx.Commit() // 提交     return &emptypb.Empty{}, nil}
      Redis 分布式鎖實(shí)現(xiàn)
      func (*InventoryServer) RedisSell(ctx context.Context, req *proto.SellInfo) (*emptypb.Empty, error) {     // redis 分布式鎖     pool := goredis.NewPool(global.Redis)     rs := redsync.New(pool)     tx := global.DB.Begin()     for _, good := range req.GoodsInfo {         mutex := rs.NewMutex(fmt.Sprintf("goods_%d", good.GoodsId))         if err := mutex.Lock(); err != nil {             return nil, status.Errorf(codes.Internal, "redis:分布式鎖獲取異常")         }         var i model.Inventory        if result := global.DB.Where(&model.Inventory{Goods: good.GoodsId}).First(&i); result.RowsAffected == 0 {             tx.Rollback()             return nil, status.Errorf(codes.InvalidArgument, "未找到此商品的庫(kù)存信息")         }         if i.Stocks < good.Num {             tx.Rollback()             return nil, status.Errorf(codes.ResourceExhausted, "此商品的庫(kù)存不足")         }         i.Stocks -= good.Num         tx.Save(&i)         if ok, err := mutex.Unlock(); !ok || err != nil {             return nil, status.Errorf(codes.Internal, "redis:分布式鎖釋放異常")         }     }     tx.Commit()     return &emptypb.Empty{}, nil}

      測(cè)試

      涉及到服務(wù)、數(shù)據(jù)庫(kù)等環(huán)境,此測(cè)試為偽代碼

      func main() {   var w sync.WaitGroup   w.Add(20)   for i := 0; i < 20; i++ {       go TestForUpdateSell(&w) // 模擬并發(fā)請(qǐng)求   }   w.Wait()}func TestForUpdateSell(wg *sync.WaitGroup) {      defer wg.Done()   _, err := invClient.Sell(context.Background(), &proto.SellInfo{       GoodsInfo: []*proto.GoodsInvInfo{      {GoodsId: 16, Num: 1},   //{GoodsId: 16, Num: 10},       },   })   if err != nil {       panic(err)  }   fmt.Println("庫(kù)存扣減成功")}

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)