Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Timeout for QueryRow method call using the database/sql package in Golang

Tags:

go

What is the appropriate way to implement a timeout for a QueryRow method call using the database/sql package in Golang? There have been a lot of discussion about this topic and I like to know if there is a solution/best practice in golang 1.7 other than using the context package like described here:

Ability to timeout when wating for the connection from the pool

Further, it seems that the context support has been implemented recently. What would be the appropriate way to use the context to timeout connections?

like image 695
user937284 Avatar asked Oct 06 '16 06:10

user937284


1 Answers

As far as go 1.7, you will have to implement your own functionality at the following levels:

  • pool level (question link)
  • query level, have to implement your own
    Query(query string, args ...interface{}) (*Rows, error)
  • Database level set the query timeout using transactions, i.e. in SQL Server, one may use EXEC sp_configure 'remote query timeout', 10. This design though faults its need for more round trips to the server.

I would suggest to switch to at least go 1.8, most database operations now have a context alternative, many changes can be found at this write up

Example:

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

Output:

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
like image 116
will7200 Avatar answered Oct 14 '22 07:10

will7200