当我使用VPN和VPN接口连接到数据库(使用标准的go sql库)时,当我尝试进行SQL查询时,无论接口是否同时启动,都会有75秒超时。我想将此超时时间缩短到一段合理的时间,因此在这种情况下我的应用程序不会被冻结75秒。
db, err := sql.Open(driverName, dataSourceName)
是否可以通过db
变量以某种方式设置它?
答案 0 :(得分:1)
从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, 1*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()
来创建父项。
答案 1 :(得分:1)
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")
等...
答案 2 :(得分:0)
我像这样使用PingContext:
// Please remember that sql.Open only validate argument
// without creating connection. Ping/PingContext do that.
db, err := sql.Open(config.DATABASE_DRIVER, config.DATABASE_URL)
if err != nil {
// log.Fatal(err)
log.Println(err) // continue for dev only. Should be Fatal in production mode
}
defer db.Close()
// Create database connection with context
ctx, cancel := context.WithTimeout(context.Background(), time.Second*15)
defer cancel()
err = db.PingContext(ctx)
if err != nil {
// log.Fatal(err)
log.Println(err) //should be Fatal in production mode
}
但是ping仍然花了我1分钟。还有其他想法吗?