From db166807c77b3265a54d02b6e5c95f11a14fe3c1 Mon Sep 17 00:00:00 2001 From: huang Date: Fri, 27 Mar 2026 22:50:18 +0800 Subject: [PATCH] =?UTF-8?q?fix(01-05):=20=E6=8F=90=E7=8E=B0=E5=86=BB?= =?UTF-8?q?=E7=BB=93=E5=B9=B6=E5=8F=91=E6=A0=A1=E9=AA=8C=E7=BC=BA=E5=A4=B1?= =?UTF-8?q?=EF=BC=88CRITICAL-08=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 冻结余额改为 result := tx...Updates(),分离结果对象 - 检查 result.Error 处理数据库错误 - 检查 result.RowsAffected == 0 防止并发余额不足时仍创建提现单 - RowsAffected == 0 时返回 errors.New(CodeInsufficientBalance, ...) --- internal/service/my_commission/service.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/internal/service/my_commission/service.go b/internal/service/my_commission/service.go index 8a0dd9d..a2b39fa 100644 --- a/internal/service/my_commission/service.go +++ b/internal/service/my_commission/service.go @@ -159,14 +159,19 @@ func (s *Service) CreateWithdrawalRequest(ctx context.Context, req *dto.CreateMy var withdrawalRequest *model.CommissionWithdrawalRequest err = s.db.Transaction(func(tx *gorm.DB) error { - // 冻结余额 - if err := tx.WithContext(ctx).Model(&model.AgentWallet{}). + // 冻结余额(使用条件更新 + RowsAffected 校验,防止并发重复提现) + result := tx.WithContext(ctx).Model(&model.AgentWallet{}). Where("id = ? AND balance >= ?", wallet.ID, req.Amount). Updates(map[string]interface{}{ "balance": gorm.Expr("balance - ?", req.Amount), "frozen_balance": gorm.Expr("frozen_balance + ?", req.Amount), - }).Error; err != nil { - return errors.Wrap(errors.CodeInternalError, err, "冻结余额失败") + }) + if result.Error != nil { + return errors.Wrap(errors.CodeInternalError, result.Error, "冻结余额失败") + } + // RowsAffected == 0 说明余额已不足(并发场景下被其他请求先行扣减) + if result.RowsAffected == 0 { + return errors.New(errors.CodeInsufficientBalance, "余额不足或并发冲突,请稍后重试") } // 创建提现申请