Skip to content

Instantly share code, notes, and snippets.

@pbnjay
Created April 11, 2016 15:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pbnjay/96f829f8aa77d7ae1d88bca094e5d6ec to your computer and use it in GitHub Desktop.
Save pbnjay/96f829f8aa77d7ae1d88bca094e5d6ec to your computer and use it in GitHub Desktop.
cannot cancel postgres query outside of transaction
package main
import (
"database/sql"
"flag"
"log"
"time"
_ "github.com/lib/pq"
)
func withTx(db *sql.DB, cancelAfter time.Duration, result chan string) {
tx, err := db.Begin()
if err != nil {
panic(err)
}
// approx ~45s on a 3.1Ghz i7
SQL := `select sum(length(replace(generate_series::bigint::bit(64)::text,'0','')))
from generate_series(0,10e6);`
nbits := ""
time.AfterFunc(cancelAfter, func() {
result <- "timeout!"
tx.Rollback()
})
err = tx.QueryRow(SQL).Scan(&nbits)
if err != nil {
panic(err)
}
result <- nbits
tx.Commit()
}
func withoutTx(db *sql.DB, cancelAfter time.Duration, result chan string) {
// approx ~45s on a 3.1Ghz i7
SQL := `select sum(length(replace(generate_series::bigint::bit(64)::text,'0','')))
from generate_series(0,10e6);`
nbits := ""
time.AfterFunc(cancelAfter, func() {
result <- "timeout!"
db.Close()
})
err := db.QueryRow(SQL).Scan(&nbits)
if err != nil {
panic(err)
}
result <- nbits
}
func main() {
useTx := flag.Bool("tx", false, "try in a transaction")
cancelAfter := flag.Duration("w", time.Second*2, "how long to wait for response")
connstr := flag.String("db", "sslmode=disable", "postgres connection string")
flag.Parse()
db, _ := sql.Open("postgres", *connstr)
result := make(chan string)
go func() {
res := <-result
log.Println("RESULT: ", res)
}()
if *useTx {
go withTx(db, *cancelAfter, result)
} else {
go withoutTx(db, *cancelAfter, result)
}
log.Println("sleeping 1 min - watch CPU for DB process")
time.Sleep(time.Minute)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment