gorm.Open(
postgres.Open(<>),
&gorm.Config{
Retry: &gorm.RetryConfig{
RetryOnDeadlock: true,
RetryInterval: time.Second,
RetryLimit: 10,
RetryableFunc: func(err error) bool { // 检测是否是瞬态错误
if pgErr, ok := err.(*pgconn.PgError); ok {
switch pgErr.Code {
case "40001":
return true
}
}
return false
},
},
},
)
在这个例子中,使用了Postgres的pgconn.PgError类型来检测错误是否是瞬态错误。如果是,就会按照Retry配置进行重试。如果在RetryLimit次数内重试失败,则会返回错误。
func WithRetry(fn func() error) error {
maxAttempts := 10
backoff := time.Second
for i := 0; i < maxAttempts; i++ {
err := fn()
if err == nil {
return nil
}
if !isTransientError(err) {
return err
}
if i == (maxAttempts - 1) { //到达最大尝试次数
return err
}
time.Sleep(backoff)
backoff *= 2
}
return nil
}
在这个例子中,函数WithRetry可以接受一个类似于Postgres事务的函数,它可能会在在某些情况下返回瞬态错误。WithRetry将会采取稳健的策略,最多重