-
-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Occasional sql: transaction has already been committed or rolled back errors #43
Comments
I am also getting this since |
should be fixed by commit now. |
@l3pp4rd sorry but I am still getting the errors even when using v0.1.5. Using v0.1.3 shows no errors. |
I'm also experiencing it on |
I think I've tracked this down. You can reproduce it by creating a db then issuing an failing testfunc TestShouldHandleStmtsWithoutContextPollution(t *testing.T) {
t.Parallel()
for _, driver := range drivers() {
t.Run(driver, func(t *testing.T) {
db, err := sql.Open(driver, "contextpollution")
if err != nil {
t.Fatalf(driver+": failed to open a connection, have you run 'make test'? err: %s", err)
}
defer db.Close()
const insertSQL = "INSERT INTO users (username, email) VALUES (?, ?)"
ctx1, cancel1 := context.WithCancel(context.Background())
defer cancel1()
_, err = db.ExecContext(ctx1, insertSQL, "first", "[email protected]")
if err != nil {
t.Fatalf("unexpected error inserting user 1: %s", err)
}
cancel1()
ctx2, cancel2 := context.WithCancel(context.Background())
defer cancel2()
_, err = db.ExecContext(ctx2, insertSQL, "second", "[email protected]")
if err != nil {
t.Fatalf("unexpected error inserting user 2: %s", err)
}
cancel2()
rows, err := db.QueryContext(context.Background(), "select username from users")
if err != nil {
t.Fatalf("unexpected error querying users: %s", err)
}
defer rows.Close()
var users []string
for rows.Next() {
var user string
err := rows.Scan(&user)
if err != nil {
t.Errorf("unexpected scan failure: %s", err)
continue
}
users = append(users, user)
}
sort.Strings(users)
wanted := []string{"first", "second"}
if len(users) != 2 {
t.Fatalf("invalid users received; want=%v\tgot=%v", wanted, users)
}
for i, want := range wanted {
if got := users[i]; want != got {
t.Errorf("invalid user; want=%s\tgot=%s", want, got)
}
}
})
}
} |
submitted PR to address the context pollution issue. Its passing all tests and runs without a hitch locally as well. Fixes the issues I was seeing. @veqryn, I'm curious if you'll get errors with the branch I just pushed to fix an issue with context handling. Its fixed both gorm and sqlx tests locally. |
now that PR #48 has merged, I think its safe to close this issue |
@samsondav, I’m going to close this issue. It should be resolved now. Feel free to return if the issue resurfaces on v0.1.6 or later 👍 |
We're seeing this in our tests. Our testcases each have their own context that gets cancelled when the testcase finishes. There is a race condition that the whole transaction may be canceled and the next testcase will use the canceled Lines 56 to 58 in 5bd9aad
As a temporary fix, we just removed the whole goroutine to prevent the global transaction being rolled back by a single operation's context. |
By inserting a delay before the context gets canceled gives the goroutine in |
We are seeing
transaction has already been committed or rolled back errors
if we try to use the database "too quickly" after initializing it, with a cancel context.Code looks like this:
Note that this error about "transaction already committed or rolled back" has nothing to do with postgres (actually the transaction never gets closed). The postgres logs look like this:
It must be a timing issue because it can be resolved by inserting a sleep or gosched here:
Note that I was running this test with a parallelism flag of 1 - single threaded mode.
UPDATE:
It seems that calling
runtime.Gosched()
only sometimes fixes it - not always. Callingdb.Exec('SELECT 1')
in place of that seems to be a more reliable fix.The text was updated successfully, but these errors were encountered: