fix(worker): 防止事务泄漏并恢复滞留队列
为 PostgreSQL 连接增加可配置的事务空闲与锁等待超时,并在请求取消或 Worker 退出后使用独立有界上下文回滚事务。\n\n恢复过期任务时按批次使用 SKIP LOCKED,周期重建缺失或终态 River Job;锁等待超时只在确认尚未提交上游时安全重排,避免重复执行和重复结算。\n\n验证:完整 Go 测试、go vet、生产 Kustomize 渲染、gofmt 与 git diff --check 均通过。
This commit is contained in:
@@ -20,7 +20,7 @@ func (s *Store) ReserveIdentityPairingStart(ctx context.Context, attemptID strin
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
defer rollbackTransaction(tx)
|
||||
if _, err := tx.Exec(ctx, `DELETE FROM gateway_identity_pairing_start_reservation
|
||||
WHERE state='starting' AND expires_at <= now()`); err != nil {
|
||||
return err
|
||||
@@ -68,7 +68,7 @@ func (s *Store) CommitIdentityPairingStart(ctx context.Context, revision identit
|
||||
if err != nil {
|
||||
return identity.PairingExchange{}, err
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
defer rollbackTransaction(tx)
|
||||
var reserved bool
|
||||
if err := tx.QueryRow(ctx, `SELECT true FROM gateway_identity_pairing_start_reservation
|
||||
WHERE singleton=true AND attempt_id=$1::uuid AND state='starting' FOR UPDATE`, exchange.ID).Scan(&reserved); errors.Is(err, pgx.ErrNoRows) {
|
||||
@@ -256,7 +256,7 @@ func (s *Store) UpdateIdentityPairingExchange(ctx context.Context, id string, ex
|
||||
if err != nil {
|
||||
return identity.PairingExchange{}, err
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
defer rollbackTransaction(tx)
|
||||
exchange, err := scanIdentityPairing(tx.QueryRow(ctx, `
|
||||
UPDATE gateway_identity_onboarding_exchanges SET status=$3,remote_version=$4,last_error_category=NULLIF($5,''),
|
||||
auth_center_audit_id=COALESCE(NULLIF($6,''),auth_center_audit_id),version=version+1,updated_at=now()
|
||||
@@ -297,7 +297,7 @@ func (s *Store) CancelIdentityPairingExchange(ctx context.Context, id string, ex
|
||||
if err != nil {
|
||||
return identity.PairingExchange{}, err
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
defer rollbackTransaction(tx)
|
||||
exchange, err := scanIdentityPairing(tx.QueryRow(ctx, `SELECT `+identityPairingColumns+`
|
||||
FROM gateway_identity_onboarding_exchanges WHERE id=$1::uuid FOR UPDATE`, id))
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
@@ -352,7 +352,7 @@ func (s *Store) CompleteIdentityPairingCleanup(ctx context.Context, id string, e
|
||||
if err != nil {
|
||||
return identity.PairingExchange{}, err
|
||||
}
|
||||
defer tx.Rollback(ctx)
|
||||
defer rollbackTransaction(tx)
|
||||
var revisionID string
|
||||
if err := tx.QueryRow(ctx, `SELECT revision_id::text FROM gateway_identity_onboarding_exchanges
|
||||
WHERE id=$1::uuid AND version=$2 AND status='cancelled' AND cleanup_status='pending' FOR UPDATE`, id, expectedVersion).Scan(&revisionID); errors.Is(err, pgx.ErrNoRows) {
|
||||
|
||||
Reference in New Issue
Block a user