当我使用标准的Go SQL库通过VPN连接数据库,但是VPN接口断开时,无论接口是否重新连接,当我尝试执行SQL查询时都会有75秒的超时。我想将这个超时时间减少到一些合理的时间,这样我的应用程序在这种情况下就不会被冻结了75秒。
db, err := sql.Open(driverName, dataSourceName)
是否可能通过db
变量进行设置?
当我使用标准的Go SQL库通过VPN连接数据库,但是VPN接口断开时,无论接口是否重新连接,当我尝试执行SQL查询时都会有75秒的超时。我想将这个超时时间减少到一些合理的时间,这样我的应用程序在这种情况下就不会被冻结了75秒。
db, err := sql.Open(driverName, dataSourceName)
是否可能通过db
变量进行设置?
database/sql
包没有提供一种通用的方法来超时调用database/sql.Open
。然而,通过DSN(dataSourceName)连接字符串,各个驱动程序都提供了这个功能。
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")
等等...
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()
创建一个父级上下文。
SetConnMaxLifetime
吗? - Ainar-Gsql.DB
是一个抽象层。例如,SQLite 数据库根本不使用 TCP,因为它们是基于文件的。因此,实际的 TCP 连接被隐藏在几个无法打破的抽象层后面,除非使用unsafe
。我建议在 Go 问题跟踪器上开启一个问题,描述您的情况。 - Ainar-GdataSourceName
接受一个connect_timeout
参数,也许这正是你所需要的?请查看 pq 文档。 - Alex Guerra