Обработка ошибок Azure SQL
У меня есть функция, предназначенная для обработки запросов TSQL. По сути, он пытается создать соединение с сервером, выполнить запрос, зафиксировать, а затем закрыть соединение. В настоящее время мы полагаемся на драйвер mssqldb,
поскольку серверной частью является Azure SQL. func (requester *Requester) doTransaction(ctx context.Context, isolation sql.IsolationLevel,
txFunc func(*sql.Tx) error) error {
// First, attempt to get a connection from the connection pool. If this fails return an error
conn, err := requester.conn.Conn(ctx)
if err != nil {
fmt.Printf("Conn failed, Error type: %s\n", reflect.TypeOf(err))
log.Printf("Conn failed, error: %v", err)
return err
}
// Before we continue on, ensure that the connection is clsoed and returned to the connection pool
defer func() {
if err := conn.Close(); err != nil {
log.Printf("Close failed, error: %v", err)
}
}()
// Next, start the transaction with the given context and the default isolation
tx, err := conn.BeginTx(ctx, &sql.TxOptions{Isolation: isolation, ReadOnly: false})
if err != nil {
fmt.Printf("BeginTx failed, Error type: %s\n", reflect.TypeOf(err))
log.Printf("BeginTx failed, error: %v", err)
return err
}
// Now, ensure that the transaction is either rolled back or committed before
// the function ends
defer func() {
if p := recover(); p != nil {
tx.Rollback()
panic(p)
} else if err != nil {
log.Printf("An error occurred: %v", err)
if err := tx.Rollback(); err != nil {
log.Printf("Rollback failed, error: %v", err)
}
} else {
if err := tx.Commit(); err != nil {
log.Printf("Commit failed, error: %v", err)
}
}
}()
// Finally, run the function and return the result
err = txFunc(tx)
return err
}
По большей части это работает хорошо. Однако я заметил ряд ошибок, которые возникают из-за тайм-аутов, бессерверных пауз, превышения ограничений ввода-вывода и т. Д .; Такие как:
Login error: mssql: Database 'my-db' on server 'myserver.database.windows.net' is not currently available. Please retry the connection later. If the problem persists, contact customer support, and provide them the session tracing ID of '{SOME_GUID}'.
Я бы хотел справиться с этим с некоторой отсрочкой, а не просто с ошибкой. Однако для этого мне нужно уметь каким-то образом интерпретировать ошибку. Однако все возвращенные ошибки имеют тип
*errors.errorString
. Я пробовал использовать
As(error, interface{})
чтобы проверить, была ли ошибка
mssql.Error
и это не так, я не совсем уверен, как с этим справиться. Как определить причину этих ошибок?
1 ответ
Вы можете попробовать преобразовать полученную ошибку в Error, как определено здесь, как определено здесь, с использованием утверждения типа
err:=//your operation that returns an error
//check and convert the error to a MSSQL error with more context
if msSQLErr,ok:=err.(mssql.Error);ok{
if msSQLErr.SQLErrorNumber() == someRetryableErrorCode{
//custom retry logic...
}
}
В качестве альтернативы вы можете использовать ошибки.
var msSQLErr mssql.Error
if errors.As(err,&msSQLErr){
if msSQLErr.SQLErrorNumber() == someRetryableErrorCode{
//custom retry logic...
}
}
Обновление: К сожалению, похоже, что библиотека не обертывает основные ошибки, поэтому вы не можете использовать ошибки. Это или ошибки. Что касается некоторых ошибок, например ошибок, связанных с сетью, вам придется самостоятельно сопоставить строки ошибок, используя что-то вроде строк .Содержит