fix
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
@@ -190,4 +191,58 @@ func (s *ProductSubscriptionService) SaveSubscription(ctx context.Context, subsc
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IncrementSubscriptionAPIUsage 增加订阅API使用次数(使用乐观锁,带重试机制)
|
||||
func (s *ProductSubscriptionService) IncrementSubscriptionAPIUsage(ctx context.Context, subscriptionID string, increment int64) error {
|
||||
const maxRetries = 3
|
||||
const baseDelay = 10 * time.Millisecond
|
||||
|
||||
for attempt := 0; attempt < maxRetries; attempt++ {
|
||||
// 使用乐观锁直接更新数据库
|
||||
err := s.subscriptionRepo.IncrementAPIUsageWithOptimisticLock(ctx, subscriptionID, increment)
|
||||
if err == nil {
|
||||
// 更新成功
|
||||
if attempt > 0 {
|
||||
s.logger.Info("订阅API使用次数更新成功(重试后)",
|
||||
zap.String("subscription_id", subscriptionID),
|
||||
zap.Int64("increment", increment),
|
||||
zap.Int("retry_count", attempt))
|
||||
} else {
|
||||
s.logger.Info("订阅API使用次数更新成功",
|
||||
zap.String("subscription_id", subscriptionID),
|
||||
zap.Int64("increment", increment))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 检查是否是版本冲突错误
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
// 版本冲突,等待后重试
|
||||
if attempt < maxRetries-1 {
|
||||
delay := time.Duration(attempt+1) * baseDelay
|
||||
s.logger.Debug("订阅版本冲突,准备重试",
|
||||
zap.String("subscription_id", subscriptionID),
|
||||
zap.Int("attempt", attempt+1),
|
||||
zap.Duration("delay", delay))
|
||||
time.Sleep(delay)
|
||||
continue
|
||||
}
|
||||
// 最后一次重试失败
|
||||
s.logger.Error("订阅不存在或版本冲突,重试次数已用完",
|
||||
zap.String("subscription_id", subscriptionID),
|
||||
zap.Int("max_retries", maxRetries),
|
||||
zap.Error(err))
|
||||
return fmt.Errorf("订阅不存在或已被其他操作修改(重试%d次后失败): %w", maxRetries, err)
|
||||
}
|
||||
|
||||
// 其他错误直接返回,不重试
|
||||
s.logger.Error("更新订阅API使用次数失败",
|
||||
zap.String("subscription_id", subscriptionID),
|
||||
zap.Int64("increment", increment),
|
||||
zap.Error(err))
|
||||
return fmt.Errorf("更新订阅API使用次数失败: %w", err)
|
||||
}
|
||||
|
||||
return fmt.Errorf("更新失败,已重试%d次", maxRetries)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user