diff --git a/server/order/internal/logic/createorderlogic.go b/server/order/internal/logic/createorderlogic.go index 21bf78d1..1e40a2a2 100644 --- a/server/order/internal/logic/createorderlogic.go +++ b/server/order/internal/logic/createorderlogic.go @@ -6,6 +6,8 @@ import ( "fusenapi/service/repositories" "fusenapi/utils/auth" "fusenapi/utils/basic" + "strconv" + "sync" "time" "context" @@ -34,6 +36,9 @@ func NewCreateOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Creat // func (l *CreateOrderLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { // } +var locks map[string]*sync.Mutex +var locksMutex sync.Mutex + func (l *CreateOrderLogic) CreateOrder(req *types.CreateOrderReq, userinfo *auth.UserInfo) (resp *basic.Response) { // 返回值必须调用Set重新返回, resp可以空指针调用 resp.SetStatus(basic.CodeOK, data) // userinfo 传入值时, 一定不为null @@ -41,6 +46,16 @@ func (l *CreateOrderLogic) CreateOrder(req *types.CreateOrderReq, userinfo *auth // 如果是,返回未授权的错误码 return resp.SetStatus(basic.CodeUnAuth) } + + var lockKey string + for _, v := range req.CartIds { + var vStr = strconv.Itoa(int(v)) + lockKey = lockKey + "|" + vStr + } + // 分布式锁--防止重复下单 + LockWith(lockKey) //获取锁 + fmt.Println("获取到了锁") + tPlus60Days := time.Now().AddDate(0, 0, 60).UTC() res, err := l.svcCtx.Repositories.NewOrder.Create(l.ctx, &repositories.CreateReq{ ExpectedDeliveryTime: tPlus60Days, @@ -51,6 +66,8 @@ func (l *CreateOrderLogic) CreateOrder(req *types.CreateOrderReq, userinfo *auth DeliveryMethod: constants.DELIVERYMETHODDSCLOUDSTORE, }) + UnlockWith(lockKey) //释放锁 + if err != nil { return resp.SetStatus(&res.ErrorCode) } @@ -76,6 +93,27 @@ func (l *CreateOrderLogic) CreateOrder(req *types.CreateOrderReq, userinfo *auth }) } +func LockWith(resource string) { + locksMutex.Lock() + lock, ok := locks[resource] + if !ok { + lock = &sync.Mutex{} + locks[resource] = lock + } + locksMutex.Unlock() + + lock.Lock() +} + +func UnlockWith(resource string) { + locksMutex.Lock() + lock, ok := locks[resource] + if ok { + lock.Unlock() + } + locksMutex.Unlock() +} + // 处理逻辑后 w,r 如:重定向, resp 必须重新处理 // func (l *CreateOrderLogic) AfterLogic(w http.ResponseWriter, r *http.Request, resp *basic.Response) { // // httpx.OkJsonCtx(r.Context(), w, resp)