Replies: 2 comments 3 replies
-
|
One more thing I forgot to mention: this only happens if any of the queries return an error. This is why I intentionally do not insert the |
Beta Was this translation helpful? Give feedback.
0 replies
-
|
When I run your example I do not get a conn busy error. I get the following: It's a little hard to tell the order things are happening with the defer and panic. But it appears the rollback succeeded. I also rewrote the example to go straight line. package main
import (
"context"
"log"
"os"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgxpool"
)
func main() {
ctx := context.Background()
pool, err := pgxpool.New(ctx, os.Getenv("DATABASE_URL"))
if err != nil {
log.Fatal(err)
}
defer pool.Close()
_, err = pool.Exec(ctx, "DROP TABLE IF EXISTS conn_busy_test")
if err != nil {
log.Fatalf("drop table")
}
_, err = pool.Exec(
ctx,
"CREATE TABLE conn_busy_test(id int, value text not null check (value != ''))",
)
if err != nil {
log.Fatal(err)
}
tx, err := pool.Begin(ctx)
if err != nil {
log.Fatalf("transaction: %+v", err)
}
values := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
err = insertMany(ctx, tx, values)
if err != nil {
log.Println("insertMany failed:", err)
} else {
log.Println("insertMany succeeded")
}
err = tx.Rollback(ctx)
if err != nil {
log.Println("rollback failed:", err)
} else {
log.Println("rollback succeeded")
}
}
// insertMany ends up will result in the rollback failing with the error:
// "failed to deallocate cached statement(s): conn busy"
func insertMany(ctx context.Context, tx pgx.Tx, values []int) error {
b := pgx.Batch{}
for _, v := range values {
b.Queue("INSERT INTO conn_busy_test(id) VALUES ($1) RETURNING id", v)
}
br := tx.SendBatch(ctx, &b)
defer br.Close()
ret := make([]int, len(values))
for i := range len(values) {
row := br.QueryRow()
err := row.Scan(&ret[i])
if err != nil {
return err
}
}
return nil
}
// insertMany2 does not result in the rollback failing.
func insertMany2(ctx context.Context, tx pgx.Tx, values []int) error {
ret := make([]int, len(values))
b := pgx.Batch{}
for i, v := range values {
b.Queue("INSERT INTO conn_busy_test(id) VALUES ($1) RETURNING id", v).
QueryRow(func(row pgx.Row) error {
err := row.Scan(&ret[i])
return err
})
}
br := tx.SendBatch(ctx, &b)
err := br.Close()
if err != nil {
return err
}
return nil
}
// insertMany3 does not result in the rollback failing either.
func insertMany3(ctx context.Context, tx pgx.Tx, values []int) error {
b := pgx.Batch{}
for _, v := range values {
b.Queue("INSERT INTO conn_busy_test(id) VALUES ($1)", v)
}
br := tx.SendBatch(ctx, &b)
defer br.Close()
for range len(values) {
_, err := br.Exec()
if err != nil {
return err
}
}
return nil
}It seems to work here too: |
Beta Was this translation helpful? Give feedback.
3 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
I am sending a batch using
pgx.Tx.SendBatch, but whenever I rollback the transaction, I get the error: "failed to deallocate cached statement(s): conn busy". This only happens when I manually scan the batch results instead of usingQueuedQuery(this is the code generated bysqlc). I would like to know what the reason is since this is either a bug inpgxorsqlcis generating incorrect code.Also, the error only shows up when using
QueryRowand does not happen when usingExecwhich made me think it may be related to #635.Here is a reproduction:
Beta Was this translation helpful? Give feedback.
All reactions