fix: 记账同一 trace 防重复扣款

流水 ref_id 有唯一索引,但扣款本身没有:重试/重复 flush 场景下
同一 trace 会被重复扣钱。billUser 扣款前先查 ref_id 是否已存在。
在远端记账重写基础上合并防重检查与测试。
This commit is contained in:
Sakurasan committed 2026-10-30 01:21:43 +08:00
1 parent 6cb840718f
commit a3197e2146
2 files changed
+36

No files matched your search

+29
View File
@@ -141,3 +141,32 @@ func seedModel(t *testing.T, db *gorm.DB) uint64 {
}
func strPtr(s string) *string { return &s }
// 同一 trace 重复记账(重试/重复 flush 场景)只扣一次款:流水 ref_id 有唯一索引,
// 但扣款本身没有,billUser 必须先查再扣。
func TestBillingRefIDImpotency(t *testing.T) {
db := openTestDB(t)
u := seedUser(t, db, 5)
rec := NewRecorder(db)
mk := func(trace string) *store.UsageLog {
return &store.UsageLog{TraceID: trace, UserID: u, ModelName: "m1",
Status: store.UsageStatusSuccess, Cost: 1, CreatedAt: time.Now().UTC()}
}
rec.Record(mk("dup"))
rec.Record(mk("dup"))
rec.Close()
var user store.User
if err := db.First(&user, u).Error; err != nil {
t.Fatal(err)
}
if user.Balance != 4 {
t.Errorf("balance = %v, want 4 (重复 trace 不重复扣款)", user.Balance)
}
var n int64
db.Model(&store.BalanceLog{}).Where("user_id = ?", u).Count(&n)
if n != 1 {
t.Errorf("balance logs = %d, want 1", n)
}
}