package service import ( "context" "log/slog" "time" "git.lzcwy.cn/zhengchiliu/zt-closet-backend/global" "git.lzcwy.cn/zhengchiliu/zt-closet-backend/internal/mysqldao" ) // StartOrderExpireScheduler 启动订单超时过期定时任务:每分钟将超时未支付订单批量置为已过期。 func StartOrderExpireScheduler() { go func() { slog.Info("order expire scheduler started") for { func() { defer func() { if r := recover(); r != nil { slog.Error("order expire scheduler panic", "recover", r) } }() runOrderExpire() }() time.Sleep(time.Minute) } }() } // runOrderExpire 扫描并过期超时待支付订单。条件更新天然幂等,多实例并发无害,无需分布式锁。 func runOrderExpire() { ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() ctx, span := global.Tracer.Start(ctx, "scheduler.OrderExpire") defer span.End() affected, err := mysqldao.NewOrderDao().OrderExpireByTime(ctx, nowUnix()) if err != nil { slog.ErrorContext(ctx, "expire orders failed", "error", err) return } if affected > 0 { slog.InfoContext(ctx, "expired pending orders", "count", affected) } }