在Go语言中设置SQL连接的TCP超时时间

16

当我使用标准的Go SQL库通过VPN连接数据库,但是VPN接口断开时,无论接口是否重新连接,当我尝试执行SQL查询时都会有75秒的超时。我想将这个超时时间减少到一些合理的时间,这样我的应用程序在这种情况下就不会被冻结了75秒。

db, err := sql.Open(driverName, dataSourceName)

是否可能通过db变量进行设置?


你尝试过 SetConnMaxLifetime 吗? - Ainar-G
1
问题在于 sql.DB 是一个抽象层。例如,SQLite 数据库根本不使用 TCP,因为它们是基于文件的。因此,实际的 TCP 连接被隐藏在几个无法打破的抽象层后面,除非使用 unsafe。我建议在 Go 问题跟踪器上开启一个问题,描述您的情况。 - Ainar-G
1
你必须直接使用数据库驱动程序包来指定如何进行TCP连接。根据不同的包,驱动程序可能有一个默认的Dialer,可以更改以返回修改后的连接,或者你可能需要注册一个自定义的sql.Driver来包装所需的Dialer。 - JimB
1
dataSourceName 接受一个 connect_timeout 参数,也许这正是你所需要的?请查看 pq 文档。 - Alex Guerra
这方面有任何消息吗?我相信我也遇到了同样的问题。 - openwonk
显示剩余3条评论
2个回答

30

database/sql包没有提供一种通用的方法来超时调用database/sql.Open。然而,通过DSN(dataSourceName)连接字符串,各个驱动程序都提供了这个功能。

https://github.com/lib/pq

sql.Open("postgres", "user=user dbname=dbname connect_timeout=5")

https://github.com/go-sql-driver/mysql

sql.Open("mysql", "user:password@/dbname?timeout=5s")

https://github.com/denisenkom/go-mssqldb

sql.Open("sqlserver", "sqlserver://username:password@host/instance?dial+timeout=5")

等等...


6
从Go 1.8开始,sql.DB抽象现在接受context.Context,可以用来更快地超时连接。
func (c *Client) DoLookup(ctx context.Context, id int) (string, error) {
  var name string
  // create a child context with a timeout
  newCtx, cancel := context.WithTimeout(ctx, time.Second)
  // release resources used in `newCtx` if
  // the DB operation finishes faster than the timeout
  defer cancel()

  row := c.db.QueryRowContext(newCtx, "SELECT name FROM items WHERE id = ?", id)

  err := row.Scan(&name)
  if err != nil {
    return "", err
  }

  return name, nil
}

如果你的 DoLookup 函数还没有使用 context.Context(实际上它应该使用!),你可以通过调用 context.TODO() 创建一个父级上下文。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接