Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to realize Go inventory deduction

2025-04-09 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

这篇文章主要介绍了Go库存扣减怎么实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Go库存扣减怎么实现文章都会有所收获,下面我们一起来看看吧。

Go 库存扣减的几种实现方法

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

Go Mutex 实现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, "未找到此商品的库存信息。") } if i.Stocks < good.Num { tx.Rollback() return nil, status.Errorf(codes.ResourceExhausted, "此商品的库存不足") } i.Stocks -= good.Num tx.Save(&i) } tx.Commit() m.Unlock() return &emptypb.Empty{}, nil}MySQL 悲观锁实现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, "未找到此商品的库存信息。") } if i.Stocks < good.Num { tx.Rollback() return nil, status.Errorf(codes.ResourceExhausted, "此商品的库存不足") } i.Stocks -= good.Num tx.Save(&i) } tx.Commit() return &emptypb.Empty{}, nil}MySQL 乐观锁实现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 { // 并发请求相同条件比较多,防止放弃掉一些请求 if result := global.DB.Where(&model.Inventory{Goods: good.GoodsId}).First(&i); result.RowsAffected == 0 { tx.Rollback() return nil, status.Errorf(codes.InvalidArgument, "未找到此商品的库存信息.") } if i.Stocks < good.Num { tx.Rollback() // 回滚 return nil, status.Errorf(codes.ResourceExhausted, "此商品的库存不足") } 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("库存扣减失败!") } else { break } } } tx.Commit() // 提交 return &emptypb.Empty{}, nil}Redis 分布式锁实现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, "未找到此商品的库存信息") } if i.Stocks < good.Num { tx.Rollback() return nil, status.Errorf(codes.ResourceExhausted, "此商品的库存不足") } 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}测试

涉及到服务、数据库等环境,此测试为伪代码

func main() { var w sync.WaitGroup w.Add(20) for i := 0; i < 20; i++ { go TestForUpdateSell(&w) // 模拟并发请求 } 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("库存扣减成功")}关于"Go库存扣减怎么实现"这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对"Go库存扣减怎么实现"知识都有一定的了解,大家如果还想学习更多知识,欢迎关注行业资讯频道。

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report