使用Golang中的database/sql包调用QueryRow方法的超时

use*_*284 8 go

QueryRow使用database/sqlGolang中的包实现方法调用超时的适当方法是什么?关于这个主题有很多讨论,我想知道golang 1.7中是否有解决方案/最佳实践,除了使用context这里描述的包:

能够在从池中连接时进行超时

此外,最近似乎已经实施上下文支持.使用上下文来超时连接的适当方法是什么?

wil*_*200 6

就 1.7 而言,您必须在以下级别实现自己的功能:

  • 池级别(问题链接)
  • 查询级别,必须实现自己的
    Query(query string, args ...interface{}) (*Rows, error)
  • 数据库级别使用事务设置查询超时,即在 SQL Server 中,可以使用EXEC sp_configure 'remote query timeout', 10. 这种设计虽然错误地需要更多的往返服务器。

我建议切换到至少1.8走,大多数数据库操作现在有一个上下文选择,许多变化可以在这个写找到

示例

package main

import (
    "context"
    "database/sql"
    "log"
    "time"

    _ "github.com/jinzhu/gorm/dialects/sqlite"
)

func main() {
    db, err := sql.Open("sqlite3", "/tmp/gorm.db")
    if err != nil {
        log.Panic(err)
    }
    ctx := context.Background()
    ctx, cancel := context.WithTimeout(ctx, time.Microsecond*10)
    defer cancel()
    res := db.QueryRowContext(ctx, "select id from orders")
    id := -1
    if err := res.Scan(&id); err != nil {
        log.Panic(err)
    }
    log.Print(id)
}
Run Code Online (Sandbox Code Playgroud)

输出

2018/06/18 19:19:03 interrupted
panic: interrupted

goroutine 1 [running]:
log.Panic(0xc420053f48, 0x1, 0x1)
        /usr/local/Cellar/go/1.10.1/libexec/src/log/log.go:326 +0xc0
main.main()
        /tmp/main.go:23 +0x226
exit status 2
Run Code Online (Sandbox Code Playgroud)