如何修复ASP.NET Core Web API中RedeemCode方法的数据库更新逻辑?
兑换码兑换方法的修复实现
当前代码仅更新用户余额,未标记兑换码为已使用,会导致重复兑换问题。以下是修复后的实现,确保兑换操作的原子性与数据一致性:
修复后的完整代码
public void RedeemCode(Codes code, int userId) { using (var tx = _dbConnection.BeginTransaction()) { try { UpdateUserBalance(code, userId, tx); MarkCodeAsUsed(code.Id, userId, tx); tx.Commit(); } catch { tx.Rollback(); throw; } } } private void UpdateUserBalance(Codes code, int userId, IDbTransaction tx) { var amount = code.Amount; _dbConnection.Execute(@$" UPDATE {nameof(User)} SET {nameof(User.Balance)} = {nameof(User.Balance)} + @amount WHERE {nameof(User.Id)} = @userId", new { userId, amount }, transaction: tx); } private void MarkCodeAsUsed(int codeId, int userId, IDbTransaction tx) { _dbConnection.Execute(@$" UPDATE {nameof(Codes)} SET {nameof(Codes.IsUsed)} = 1, {nameof(Codes.UsedByUserId)} = @userId, {nameof(Codes.UsedAt)} = GETDATE() WHERE {nameof(Codes.Id)} = @codeId", new { codeId, userId }, transaction: tx); }
核心改进点
- 原子性保障:所有数据库操作(余额更新+兑换码标记)都在同一事务中执行,任一操作失败则全部回滚,避免数据不一致
- 兑换码状态标记:新增
MarkCodeAsUsed方法,将兑换码设为已使用状态,同时记录使用用户ID和时间,彻底防止重复兑换 - 事务传递:将事务对象传递给子方法,确保所有操作共享同一事务上下文
- 异常处理:捕获异常后回滚事务,避免半完成状态的数据残留
内容的提问来源于stack exchange,提问作者Test Patel
相关产品推荐
相关产品推荐

