You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It looks like I have found some unexpected behavior with this library when it comes to how context and transactions interact.
Description
When using a context that has a cancel function with db.QueryContext and similar functions, sometimes, when that cancel function is called, the transaction is rolled back, returning sql: transaction has already been committed or rolled back on subsequent calls.
Reproduction
This code reproduces the issue about 20% of times that it runs. After the aux function countUsers returns and dispatches the cancel function, the next call will return the above transaction error.
funcmain() {
txdb.Register("mysqltx", "mysql", "root@/txdb_test")
db, err:=sql.Open("mysqltx", fmt.Sprintf("connection_%d", time.Now().UnixNano()))
iferr!=nil {
log.Fatalf("could not open DB tx: %s", err.Error())
}
n, err:=countUsers(db)
iferr!=nil {
log.Fatalf("error doing query: %s", err.Error())
}
log.Printf("Found %d users", n)
iferr:=db.Close(); err!=nil {
// error herelog.Fatalf("could not close DB tx: %s", err.Error())
}
}
funccountUsers(db*sql.DB) (int, error) {
ctx, cancel:=context.WithTimeout(context.Background(), 100*time.Millisecond)
defercancel()
varnintiferr:=db.QueryRowContext(ctx, "SELECT COUNT(*) FROM user").Scan(&n); err!=nil {
return0, err
}
returnn, nil
}
Notes
Go version: go version go1.13.5 linux/amd64
MySQL version mysql:5.7.12 Docker image
Not able to reproduce this in my example, but on my project that I've found this issue, I'm also seeing series of these errors:
Hi, if you see busy buffer errors, it means that most likely you are not closing sql.Rows before calling another exec or anything on that transaction.
In transaction you acquire a single connection, if you query rows and do not close it before calling any other exec or query on that tx, then you definitely will endup with timeout of tx or context, whichever happens first. It will simply block.
The best practice is in any case, just to release rows when you read it, do not defer the close if you happen to issue another call. If not within transaction, it would use more connections to db than needed or block if you run out of connections.
It looks like I have found some unexpected behavior with this library when it comes to how context and transactions interact.
Description
When using a context that has a cancel function with
db.QueryContext
and similar functions, sometimes, when that cancel function is called, the transaction is rolled back, returningsql: transaction has already been committed or rolled back
on subsequent calls.Reproduction
This code reproduces the issue about 20% of times that it runs. After the aux function
countUsers
returns and dispatches the cancel function, the next call will return the above transaction error.Notes
go version go1.13.5 linux/amd64
mysql:5.7.12
Docker imageLet me know if I'm doing anything improperly or if you need any more information.
Thanks!
The text was updated successfully, but these errors were encountered: