diff options
| author | Stefan Majewsky <majewsky@gmx.net> | 2026-08-05 19:43:42 +0200 |
|---|---|---|
| committer | Stefan Majewsky <majewsky@gmx.net> | 2026-08-05 19:43:42 +0200 |
| commit | 972e3e4fbd88ace9494b6a8c639119852770636b (patch) | |
| tree | b8a7459e947ce367ef58226b6b92297180633327 | |
| parent | 8bb08a0847eff3e92044685307cd620674b9b4ff (diff) | |
| download | go-gg-972e3e4fbd88ace9494b6a8c639119852770636b.tar.gz | |
pgruntime: protect against concurrent migrations
| -rw-r--r-- | CHANGELOG.md | 6 | ||||
| -rw-r--r-- | pgruntime/behavior.go | 17 |
2 files changed, 22 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 77b3972..e7bfdf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ SPDX-FileCopyrightText: 2026 Stefan Majewsky <majewsky@gmx.net> SPDX-License-Identifier: Apache-2.0 --> +# v1.13.2 (TBD) + +Changes: + +- pgruntime: Add transaction locking to protect against concurrent migrations. + # v1.13.1 (2026-08-05) Changes: diff --git a/pgruntime/behavior.go b/pgruntime/behavior.go index 3ffff1e..03ff338 100644 --- a/pgruntime/behavior.go +++ b/pgruntime/behavior.go @@ -110,7 +110,22 @@ func applyMigrations(ctx context.Context, db gsql.ConnectionHandle, migrations m // apply migrations for _, version := range pendingVersions { err := db.GSQLTransact(ctx, func(tx gsql.Handle) error { - _, err := execQuery(ctx, db, migrations[version], nil) + // ensure that nobody else is migrating until we are done + var actualVersion int64 + err := queryRow(ctx, db, `SELECT version FROM schema_migrations FOR UPDATE`, nil, []any{&actualVersion}) + if err != nil { + return fmt.Errorf("could not obtain lock for schema migration: %w", err) + } + + // ensure that nobody else migrated just before we started our transaction block + if version <= actualVersion { + return fmt.Errorf("tried to perform migration to version %d, but schema is already at version %d (multiple migrations might be running concurrently)", + version, actualVersion, + ) + } + + // perform the next migration + _, err = execQuery(ctx, db, migrations[version], nil) if err != nil { return fmt.Errorf("could not execute schema migration: %w", err) } |
