在Go中为SQL连接设置TCP超时

时间:2016-11-10 12:36:26

标签: database go tcp connection

当我使用VPN和VPN接口连接到数据库(使用标准的go sql库)时,当我尝试进行SQL查询时,无论接口是否同时启动,都会有75秒超时。我想将此超时时间缩短到一段合理的时间,因此在这种情况下我的应用程序不会被冻结75秒。

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

是否可以通过db变量以某种方式设置它?

3 个答案:

答案 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)连接字符串提供此功能。

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")

等...

答案 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分钟。还有其他想法吗?