-
-
Notifications
You must be signed in to change notification settings - Fork 48
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
Savepoint does not exists if using several transactions #55
Comments
I understand that we should collect statements before opening transactions, but there are a lot of data and we use |
It appears this is what happened
According to psql doc,
So Seems to me that you could avoid this issue if you don't have begin() and commit() calls intertwined:
not sure if this is practical for you though :) |
@AlwxSin My project pgtestdb handles opening multiple transactions before committing them as you'd expect, no issues. You don't need to worry about committing transactions in any specific order. Consider giving it a shot! This example requires a postgres server available at # file: docker-compose.yml
version: "3.6"
services:
testdb:
image: postgres:15
environment:
POSTGRES_PASSWORD: password
restart: unless-stopped
volumes:
# Uses a tmpfs volume to make tests extremely fast. The data in test
# databases is not persisted across restarts, nor does it need to be.
- type: tmpfs
target: /var/lib/postgresql/data/
command:
- "postgres"
- "-c"
- "fsync=off"
- "-c"
- "shared_buffers=1024MB"
- "-c"
- "synchronous_commit=off"
- "-c"
- "full_page_writes=off"
- "-c"
- "log_statement=all"
- "-c"
- "max_connections=1000"
ports:
- "5433:5432" -- file: 01_initial.sql
create table users (
id bigint primary key generated always as identity,
username text unique not null,
email text unique not null
); // file: main_test.go
package main_test
import (
"database/sql"
"embed"
"fmt"
"testing"
_ "github.com/lib/pq" // "postgres" driver
"github.com/peterldowns/pgmigrate"
"github.com/peterldowns/pgtestdb"
"github.com/peterldowns/pgtestdb/migrators/pgmigrator"
"github.com/peterldowns/testy/assert"
)
// Embeds the migration file
//go:embed *.sql
var migrationsFS embed.FS
func TestPostgresMultipleTx(t *testing.T) {
t.Parallel()
logger := pgmigrate.NewTestLogger(t)
pgm, err := pgmigrator.New(migrationsFS, pgmigrator.WithLogger(logger))
assert.Nil(t, err)
db := pgtestdb.New(t, pgtestdb.Config{
DriverName: "postgres",
Host: "localhost",
User: "postgres",
Password: "password",
Port: "5433",
Options: "sslmode=disable",
}, pgm)
// Begin 6 transactions, each inserting a user, but don't commit.
txs := make([]*sql.Tx, 0)
for i, letter := range []string{"p", "o", "s", "g", "e", "s"} {
tx, _ := db.Begin()
txs = append(txs, tx)
username := fmt.Sprintf("user-%d-%s", i, letter)
email := fmt.Sprintf("%s@example-%d-%s.com", username, i, letter)
_, err := tx.Exec(`INSERT INTO users (username, email) VALUES( $1, $2 )`, username, email)
assert.Nil(t, err)
}
// Confirm that there are 0 users in the database.
var beforeCommittedCount int
err = db.QueryRow("SELECT COUNT(id) FROM users").Scan(&beforeCommittedCount)
assert.Nil(t, err)
assert.Equal(t, 0, beforeCommittedCount)
// shuffle the array txs so the elements are now in random order, they can
// be committed in any order without a problem.
rand.Shuffle(len(txs), func(i, j int) { txs[i], txs[j] = txs[j], txs[i] })
// Commit each of the transactions, one-by-one.
for i, tx := range txs {
err := tx.Commit()
assert.Nil(t, err)
var count int
err = db.QueryRow("SELECT COUNT(id) FROM users").Scan(&count)
assert.Nil(t, err)
assert.Equal(t, i+1, count)
}
// Confirm the final count is 6 users in the database.
var finalCount int
err = db.QueryRow("SELECT COUNT(id) FROM users").Scan(&finalCount)
assert.Nil(t, err)
assert.Equal(t, 6, finalCount)
} |
In my project we prepare several different transactions before executing and committing them
It works in production, but fails in tests with error
savepoint "tx_2" does not exist
.Here is test example
The text was updated successfully, but these errors were encountered: