package mysql import ( "context" "fmt" "time" ) func resourceOutboxEvent(eventType string, commandID string, userID int64, resourceID int64, payload any, nowMs int64) walletOutboxEvent { eventKey := fmt.Sprintf("%s|%s|%d|%d", eventType, commandID, userID, resourceID) eventID := "wev_" + stableHash(eventKey) return walletOutboxEvent{ EventID: eventID, EventType: eventType, // 资源目录、赠送和装备变更没有金融 ledger transaction;使用稳定 event_id // 作为 correlation transaction_id,既满足统一 MQ envelope,又能从消息直接 // 回查唯一 outbox 行。相同业务命令重试会得到同一 ID,不会制造新事实。 TransactionID: eventID, CommandID: commandID, UserID: userID, AssetType: resourceOutboxAsset, Payload: payload, CreatedAtMS: nowMs, } } func (r *Repository) insertResourceOutboxNoTx(ctx context.Context, eventType string, commandID string, userID int64, resourceID int64, payload any) error { tx, err := r.db.BeginTx(ctx, nil) if err != nil { return err } defer func() { _ = tx.Rollback() }() nowMs := time.Now().UnixMilli() if err := r.insertWalletOutbox(ctx, tx, []walletOutboxEvent{resourceOutboxEvent(eventType, commandID, userID, resourceID, payload, nowMs)}); err != nil { return err } return tx.Commit() }