Guard against nested transactions

Not sure how to do this in PostgreSQL, so use a parameter.
This commit is contained in:
Christopher Baines 2025-04-19 13:19:03 +01:00
parent 982121c308
commit 2430bc4307
2 changed files with 111 additions and 93 deletions

View file

@ -19,6 +19,7 @@
#:use-module (system foreign) #:use-module (system foreign)
#:use-module (ice-9 match) #:use-module (ice-9 match)
#:use-module (ice-9 threads) #:use-module (ice-9 threads)
#:use-module (ice-9 exceptions)
#:use-module (squee) #:use-module (squee)
#:use-module (prometheus) #:use-module (prometheus)
#:use-module (guix-data-service config) #:use-module (guix-data-service config)
@ -31,6 +32,7 @@
open-postgresql-connection open-postgresql-connection
close-postgresql-connection close-postgresql-connection
%postgresql-in-transaction?
with-postgresql-transaction with-postgresql-transaction
check-test-database! check-test-database!
@ -205,8 +207,16 @@
(define %postgresql-connections-name (define %postgresql-connections-name
(make-parameter #f)) (make-parameter #f))
(define %postgresql-in-transaction?
(make-parameter #f))
(define* (with-postgresql-transaction conn f (define* (with-postgresql-transaction conn f
#:key always-rollback?) #:key always-rollback?)
(when (%postgresql-in-transaction?)
(raise-exception
(make-exception-with-message
"nested transaction detected")))
(exec-query conn "BEGIN;") (exec-query conn "BEGIN;")
(with-exception-handler (with-exception-handler
@ -219,7 +229,10 @@
;; TODO Include the stack in the exception via knots ;; TODO Include the stack in the exception via knots
(raise-exception exn)) (raise-exception exn))
(lambda () (lambda ()
(let ((result (f conn))) (let ((result
(parameterize
((%postgresql-in-transaction? #t))
(f conn))))
(exec-query conn (if always-rollback? (exec-query conn (if always-rollback?
"ROLLBACK;" "ROLLBACK;"
"COMMIT;")) "COMMIT;"))

View file

@ -2562,6 +2562,8 @@ SELECT store_path FROM derivation_source_files WHERE id = $1"
(define guix-revision-id-promise (define guix-revision-id-promise
(fibers-delay (fibers-delay
(lambda () (lambda ()
(parameterize
((%postgresql-in-transaction? #f))
(retry-on-missing-store-item (retry-on-missing-store-item
(lambda () (lambda ()
(let ((guix-source (let ((guix-source
@ -2574,7 +2576,7 @@ SELECT store_path FROM derivation_source_files WHERE id = $1"
channel-derivations-by-system))) channel-derivations-by-system)))
#:on-exception #:on-exception
(lambda () (lambda ()
(fibers-promise-reset channel-derivations-by-system-promise)))))) (fibers-promise-reset channel-derivations-by-system-promise)))))))
;; Prompt getting the guix-revision-id as soon as possible ;; Prompt getting the guix-revision-id as soon as possible
(spawn-fiber (spawn-fiber
@ -3032,6 +3034,9 @@ SKIP LOCKED")
(make-channel)) (make-channel))
(define result (define result
(parameterize
;; Mimic the behaviour of with-postgresql-transaction
((%postgresql-in-transaction? #t))
(with-postgresql-connection (with-postgresql-connection
(simple-format #f "load-new-guix-revision ~A" id) (simple-format #f "load-new-guix-revision ~A" id)
(lambda (conn) (lambda (conn)
@ -3120,7 +3125,7 @@ SKIP LOCKED")
(() (()
(exec-query conn "ROLLBACK") (exec-query conn "ROLLBACK")
(simple-format #t "job ~A not found to be processed\n" (simple-format #t "job ~A not found to be processed\n"
id)))))) id)))))))
(when result (when result
(fibers-parallel (fibers-parallel