yumosx commented on issue #904:
URL:
https://github.com/apache/incubator-seata-go/issues/904#issuecomment-3345500379
代码使用原子性更新好像就没啥问题了:
```diff
func (a *AccountService) Deduct(ctx context.Context, account model.Account)
error {
- var userAccount model.Account
- err := a.db.WithContext(ctx).Where("user_id = ?",
account.UserID).First(&userAccount).Error
- if err != nil {
- if errors.Is(err, gorm.ErrRecordNotFound) {
- return fmt.Errorf("account not found for user_id:
%d", account.UserID)
- }
- return fmt.Errorf("failed to query account: %w", err)
- }
+ result := a.db.WithContext(ctx).Model(&model.Account{}).
+ Where("user_id = ? AND balance >= ?", account.UserID,
account.Balance).
+ UpdateColumn("balance", gorm.Expr("balance - ?",
account.Balance))
- if userAccount.Balance < account.Balance {
- return fmt.Errorf("insufficient balance: current balance %d,
required %d", userAccount.Balance, account.Balance)
+ if result.Error != nil {
+ return fmt.Errorf("failed to deduct balance: %w",
result.Error)
}
- // 计算扣减后的新余额
- newBalance := userAccount.Balance - account.Balance
- err = a.db.WithContext(ctx).Model(&model.Account{}).
- Where("user_id = ?", account.UserID).
- Update("balance", newBalance).Error
- if err != nil {
- return fmt.Errorf("failed to deduct balance: %w", err)
+ if result.RowsAffected == 0 {
+ return fmt.Errorf("insufficient balance or account not found
for user_id: %d", account.UserID)
}
return nil
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]