87b1387c创建于 2025年12月5日历史提交
文件最后提交记录最后更新时间
4 年前
3 年前
3 年前
4 年前
8 个月前
8 个月前
8 个月前
4 年前
8 个月前
8 个月前
6 年前
8 个月前
8 个月前
README

CRDB

crdb is a wrapper around the logic for issuing SQL transactions which performs retries (as required by CockroachDB).

Basic Usage

import "github.com/cockroachdb/cockroach-go/v2/crdb"

err := crdb.ExecuteTx(ctx, db, nil, func(tx *sql.Tx) error {
    // Your transaction logic here
    _, err := tx.ExecContext(ctx, "UPDATE accounts SET balance = balance - 100 WHERE id = 1")
    return err
})

Retry Policies

By default, transactions retry up to 50 times with no delay between attempts. You can customize retry behavior using context options.

Limiting Retries

// Retry up to 10 times
ctx := crdb.WithMaxRetries(context.Background(), 10)
err := crdb.ExecuteTx(ctx, db, nil, func(tx *sql.Tx) error {
    // ...
})

Unlimited Retries

// Retry indefinitely (use with caution - ensure you have a context timeout!)
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
ctx = crdb.WithMaxRetries(ctx, 0)

Disabling Retries

// Execute only once, no retries
ctx := crdb.WithNoRetries(context.Background())

Fixed Delay Between Retries

ctx := crdb.WithRetryPolicy(context.Background(), &crdb.LimitBackoffRetryPolicy{
    RetryLimit: 10,
    Delay:      100 * time.Millisecond,
})

Exponential Backoff

ctx := crdb.WithRetryPolicy(context.Background(), &crdb.ExpBackoffRetryPolicy{
    RetryLimit: 10,
    BaseDelay:  100 * time.Millisecond,  // First retry waits 100ms
    MaxDelay:   5 * time.Second,          // Cap delay at 5s
})
// Delays: 100ms, 200ms, 400ms, 800ms, 1.6s, 3.2s, 5s, 5s, 5s, 5s

Custom Retry Policies

Implement the RetryPolicy interface for custom behavior:

type RetryPolicy interface {
    NewRetry() RetryFunc
}

type RetryFunc func(err error) (delay time.Duration, retryErr error)

You can also adapt third-party backoff libraries using ExternalBackoffPolicy():

import "github.com/sethvargo/go-retry"

ctx := crdb.WithRetryPolicy(context.Background(), crdb.ExternalBackoffPolicy(func() crdb.ExternalBackoff {
    return retry.NewFibonacci(1 * time.Second)
}))

Framework Support

Subpackages provide support for popular frameworks:

Package Framework Import
crdbpgx pgx v4 (standalone) github.com/cockroachdb/cockroach-go/v2/crdb/crdbpgx
crdbpgxv5 pgx v5 (standalone) github.com/cockroachdb/cockroach-go/v2/crdb/crdbpgxv5
crdbgorm GORM github.com/cockroachdb/cockroach-go/v2/crdb/crdbgorm
crdbsqlx sqlx github.com/cockroachdb/cockroach-go/v2/crdb/crdbsqlx

Error Wrapping

When wrapping errors inside transaction functions, use %w or errors.Wrap() to preserve retry detection:

// WRONG - masks retryable error
return fmt.Errorf("failed: %s", err)

// CORRECT - preserves error for retry detection
return fmt.Errorf("failed: %w", err)

Driver Compatibility

The library detects retryable errors using the SQLState() string method, which is implemented by:

Note for Developers

If you make any changes here (especially if they modify public APIs), please verify that the code in https://github.com/cockroachdb/examples-go still works and update as necessary.