diff options
author | Christopher Baines <mail@cbaines.net> | 2021-01-16 18:25:51 +0000 |
---|---|---|
committer | Christopher Baines <mail@cbaines.net> | 2021-01-16 18:25:51 +0000 |
commit | d0c492daf37e73f40c062b2f5c9bd99f1a809680 (patch) | |
tree | b1c80ed45a32cd724d9b422ec8c10134f18d33b5 /guix-build-coordinator/datastore | |
parent | c0fb848dc635bff50e19cc91fd36e9036f3012ef (diff) | |
download | build-coordinator-d0c492daf37e73f40c062b2f5c9bd99f1a809680.tar build-coordinator-d0c492daf37e73f40c062b2f5c9bd99f1a809680.tar.gz |
Allow nesting transactions in code
You can't actually nest transactions, so just track if one is in progress, and
don't attempt to start a transaction if that's the case.
Diffstat (limited to 'guix-build-coordinator/datastore')
-rw-r--r-- | guix-build-coordinator/datastore/sqlite.scm | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/guix-build-coordinator/datastore/sqlite.scm b/guix-build-coordinator/datastore/sqlite.scm index b49ba92..8e23633 100644 --- a/guix-build-coordinator/datastore/sqlite.scm +++ b/guix-build-coordinator/datastore/sqlite.scm @@ -305,25 +305,32 @@ result)) (thunk))) +(define %current-transaction-proc + (make-parameter #f)) + (define* (datastore-call-with-transaction datastore proc #:key readonly? duration-metric-name) (define (run-proc-within-transaction db) - (sqlite-exec db "BEGIN TRANSACTION;") - (with-exception-handler - (lambda (exn) - (simple-format (current-error-port) - "error: sqlite rolling back transaction\n") - (sqlite-exec db "ROLLBACK TRANSACTION;") - (raise-exception exn)) - (lambda () - (call-with-values + (if (%current-transaction-proc) + (proc db) ; already in transaction + (begin + (sqlite-exec db "BEGIN TRANSACTION;") + (with-exception-handler + (lambda (exn) + (simple-format (current-error-port) + "error: sqlite rolling back transaction\n") + (sqlite-exec db "ROLLBACK TRANSACTION;") + (raise-exception exn)) (lambda () - (proc db)) - (lambda vals - (sqlite-exec db "COMMIT TRANSACTION;") - (apply values vals)))))) + (call-with-values + (lambda () + (parameterize ((%current-transaction-proc proc)) + (proc db))) + (lambda vals + (sqlite-exec db "COMMIT TRANSACTION;") + (apply values vals)))))))) (call-with-worker-thread (slot-ref datastore (if readonly? |