Files
tyapi-server/docs/充值记录服务优化说明.md
2025-07-28 01:46:39 +08:00

8.2 KiB

充值记录服务优化说明

优化概述

本次优化主要针对充值记录服务进行了两个重要改进:

  1. 统一钱包余额更新逻辑 - 使用钱包聚合服务的充值方法
  2. 添加事务支持 - 为所有充值相关方法添加事务保护

优化内容

1. 统一钱包余额更新逻辑

问题分析

之前的充值记录服务直接操作钱包仓储来更新余额,存在以下问题:

  • 代码重复:钱包余额更新逻辑在多个地方重复实现
  • 维护困难:余额更新逻辑变更需要在多个地方修改
  • 一致性风险:不同服务可能使用不同的余额更新逻辑

解决方案

修改充值记录服务,使用钱包聚合服务的 Recharge 方法来更新钱包余额:

修改的方法:

  • TransferRecharge - 对公转账充值
  • GiftRecharge - 赠送充值
  • HandleAlipayPaymentSuccess - 支付宝支付成功回调处理

修改前:

// 直接操作钱包仓储
w.AddBalance(amount)
ok, err := s.walletRepo.UpdateBalanceWithVersion(ctx, w.ID, w.Balance.String(), w.Version)
if err != nil {
    return nil, err
}
if !ok {
    return nil, fmt.Errorf("高并发下充值失败,请重试")
}

修改后:

// 使用钱包聚合服务
err = s.walletService.Recharge(ctx, userID, amount)
if err != nil {
    return nil, err
}

优势

  • 代码复用:统一使用钱包聚合服务的余额更新逻辑
  • 维护性:余额更新逻辑变更只需在一个地方修改
  • 一致性:确保所有充值方式使用相同的余额更新逻辑
  • 可测试性:可以独立测试钱包聚合服务的余额更新逻辑

2. 添加事务支持

问题分析

充值相关方法执行多个数据库操作:

TransferRecharge 方法:

  1. 创建充值记录
  2. 更新钱包余额
  3. 更新充值记录状态为成功

GiftRecharge 方法:

  1. 创建充值记录
  2. 更新钱包余额

HandleAlipayPaymentSuccess 方法:

  1. 更新支付宝订单状态
  2. 更新充值记录状态
  3. 更新钱包余额

如果任何一步失败,可能导致数据不一致:

  • 充值记录已创建,但钱包余额未更新
  • 支付宝订单已更新,但充值记录未更新
  • 充值记录已更新,但钱包余额未更新
  • 重复处理导致数据异常

解决方案

为所有充值相关方法添加事务支持:

添加事务的方法:

  • TransferRecharge - 对公转账充值
  • GiftRecharge - 赠送充值
  • HandleAlipayPaymentSuccess - 支付宝支付成功回调处理

修改前:

// 逐个执行更新操作,无事务保护
// TransferRecharge 示例
createdRecord, err := s.rechargeRecordRepo.Create(ctx, *rechargeRecord)
err = s.walletService.Recharge(ctx, userID, amount)
err = s.rechargeRecordRepo.Update(ctx, createdRecord)

// GiftRecharge 示例  
createdRecord, err := s.rechargeRecordRepo.Create(ctx, *rechargeRecord)
err = s.walletService.Recharge(ctx, userID, amount)

// HandleAlipayPaymentSuccess 示例
alipayOrder.MarkSuccess(tradeNo, "", "", amount, amount)
err = s.alipayOrderRepo.Update(ctx, *alipayOrder)
// ... 其他更新操作

修改后:

// 在事务中执行所有更新操作
// TransferRecharge 示例
err = s.txManager.ExecuteInTx(ctx, func(txCtx context.Context) error {
    record, err := s.rechargeRecordRepo.Create(txCtx, *rechargeRecord)
    if err != nil {
        return err
    }
    createdRecord = record

    err = s.walletService.Recharge(txCtx, userID, amount)
    if err != nil {
        return err
    }

    createdRecord.MarkSuccess()
    err = s.rechargeRecordRepo.Update(txCtx, createdRecord)
    if err != nil {
        return err
    }

    return nil
})

// GiftRecharge 示例
err = s.txManager.ExecuteInTx(ctx, func(txCtx context.Context) error {
    record, err := s.rechargeRecordRepo.Create(txCtx, *rechargeRecord)
    if err != nil {
        return err
    }
    createdRecord = record

    err = s.walletService.Recharge(txCtx, userID, amount)
    if err != nil {
        return err
    }

    return nil
})

// HandleAlipayPaymentSuccess 示例
err = s.txManager.ExecuteInTx(ctx, func(txCtx context.Context) error {
    // 更新支付宝订单状态为成功
    alipayOrder.MarkSuccess(tradeNo, "", "", amount, amount)
    err := s.alipayOrderRepo.Update(txCtx, *alipayOrder)
    if err != nil {
        return err
    }

    // 更新充值记录状态为成功
    rechargeRecord.MarkSuccess()
    err = s.rechargeRecordRepo.Update(txCtx, rechargeRecord)
    if err != nil {
        return err
    }

    // 使用钱包聚合服务更新钱包余额
    err = s.walletService.Recharge(txCtx, rechargeRecord.UserID, amount)
    if err != nil {
        return err
    }

    return nil
})

优势

  • 数据一致性:确保所有操作要么全部成功,要么全部回滚
  • 幂等性:防止重复处理导致的数据不一致
  • 错误处理:统一的错误处理和回滚机制
  • 业务完整性:保证充值记录和钱包余额状态一致
  • 原子性:所有相关操作作为一个原子单元执行

技术实现

1. 依赖注入更新

充值记录服务构造函数:

func NewRechargeRecordService(
    rechargeRecordRepo repositories.RechargeRecordRepository,
    alipayOrderRepo repositories.AlipayOrderRepository,
    walletRepo repositories.WalletRepository,
    walletService WalletAggregateService,        // 新增
    txManager *database.TransactionManager,      // 新增
    logger *zap.Logger,
) RechargeRecordService

服务结构体:

type RechargeRecordServiceImpl struct {
    rechargeRecordRepo repositories.RechargeRecordRepository
    alipayOrderRepo    repositories.AlipayOrderRepository
    walletRepo         repositories.WalletRepository
    walletService      WalletAggregateService    // 新增
    txManager          *database.TransactionManager // 新增
    logger             *zap.Logger
}

2. 事务管理

使用 shared/database.TransactionManager 进行事务管理:

  • 自动事务开始和提交
  • 异常时自动回滚
  • 支持事务超时和重试
  • 提供事务统计和监控

3. 错误处理

  • 保持原有的错误处理机制
  • 事务失败时自动回滚所有更改
  • 详细的错误日志记录
  • 幂等性检查防止重复处理

影响评估

1. 向后兼容性

  • 应用服务层接口保持不变
  • 对调用方完全透明
  • 保持原有的错误处理机制

2. 性能影响

  • 事务开销可控,仅在支付宝回调时使用
  • 减少代码重复,提高执行效率
  • 统一余额更新逻辑,减少数据库操作

3. 数据一致性

  • 显著提高数据一致性
  • 防止部分更新导致的数据不一致
  • 支持幂等性处理

4. 维护性

  • 代码更加清晰和易于维护
  • 减少重复代码
  • 统一的错误处理机制

测试建议

1. 单元测试

  • 测试钱包聚合服务的 Recharge 方法
  • 测试充值记录服务的各个方法
  • 测试事务回滚机制

2. 集成测试

  • 测试完整的支付宝充值流程
  • 测试事务失败时的回滚机制
  • 测试重复回调的处理

3. 压力测试

  • 测试高并发下的充值处理
  • 测试事务超时和重试机制
  • 测试数据库连接池的使用

监控建议

1. 业务监控

  • 监控充值成功率
  • 监控事务执行时间
  • 监控事务回滚次数

2. 技术监控

  • 监控数据库连接池使用情况
  • 监控事务超时情况
  • 监控错误率和异常情况

后续优化

1. 事件驱动

考虑使用事件驱动架构来处理充值成功后的业务逻辑:

  • 充值成功事件
  • 余额变更事件
  • 通知事件

2. 缓存优化

  • 对频繁查询的充值记录添加缓存
  • 对钱包余额添加缓存
  • 实现缓存一致性机制

3. 异步处理

  • 将非关键操作异步化
  • 使用消息队列处理充值回调
  • 实现重试机制

总结

本次优化通过统一钱包余额更新逻辑和添加事务支持,显著提高了充值记录服务的:

  1. 代码质量 - 减少重复代码,提高可维护性
  2. 数据一致性 - 确保业务操作的原子性
  3. 错误处理 - 统一的错误处理和回滚机制
  4. 可测试性 - 更好的单元测试和集成测试支持

这些改进为后续的功能扩展和维护奠定了良好的基础。