commit e54b73cfeb3b402fb012606c2ea9d7427706c9ee
parent 6b942f6213e6b2ad53b252b88a79e14bac58be71
Author: Antoine A <>
Date: Tue, 13 Oct 2026 11:16:32 +0200
common: lock for commit ordered ids
Diffstat:
2 files changed, 28 insertions(+), 17 deletions(-)
diff --git a/database-versioning/libeufin-bank-procedures.sql b/database-versioning/libeufin-bank-procedures.sql
@@ -486,6 +486,8 @@ PERFORM FROM bank_accounts
ORDER BY bank_account_id
FOR UPDATE;
+-- Lock for transaction history and revenue id commit ordering
+LOCK TABLE bank_account_transactions IN SHARE ROW EXCLUSIVE MODE;
-- now actually create the bank transaction.
-- debtor side:
INSERT INTO bank_account_transactions (
@@ -642,6 +644,8 @@ DECLARE
local_amount taler_amount;
local_taler_in_id INT8;
BEGIN
+-- Lock for incoming history id commit ordering
+LOCK TABLE taler_exchange_incoming IN SHARE ROW EXCLUSIVE MODE;
-- Register incoming transaction
INSERT INTO taler_exchange_incoming (
metadata,
diff --git a/database-versioning/libeufin-nexus-procedures.sql b/database-versioning/libeufin-nexus-procedures.sql
@@ -173,6 +173,8 @@ IF out_initiated AND NOT out_found THEN
END IF;
IF NOT out_found THEN
+ -- Lock for outgoing history id commit ordering
+ LOCK TABLE outgoing_transactions IN SHARE ROW EXCLUSIVE MODE;
-- Store the transaction in the database
INSERT INTO outgoing_transactions (
amount
@@ -335,6 +337,8 @@ IF out_found THEN
PERFORM pg_notify('nexus_revenue_tx', out_tx_id::text);
END IF;
ELSE
+ -- Lock for revenue id commit ordering
+ LOCK TABLE incoming_transactions IN SHARE ROW EXCLUSIVE MODE;
-- Store the transaction in the database
INSERT INTO incoming_transactions (
amount
@@ -373,6 +377,8 @@ IF in_type IS NOT NULL AND NOT out_talerable AND out_bounce_id IS NULL THEN
WHERE (
incoming_transaction_id IS NULL AND account_pub = in_metadata AND in_type=type AND type='reserve'
) OR authorization_pub = local_authorization_pub;
+ -- Lock for incoming history id commit ordering
+ LOCK TABLE talerable_incoming_transactions IN SHARE ROW EXCLUSIVE MODE;
-- We cannot use ON CONFLICT here because conversion use a trigger before insertion that isn't idempotent
INSERT INTO talerable_incoming_transactions (
incoming_transaction_id
@@ -706,25 +712,26 @@ IF out_reserve_pub_reuse OR out_subject_reuse THEN
END IF;
IF in_recurrent THEN
- -- Finalize one pending right now
- WITH moved_tx AS (
- DELETE FROM pending_recurrent_incoming_transactions
- WHERE incoming_transaction_id = (
- SELECT incoming_transaction_id
- FROM pending_recurrent_incoming_transactions
- JOIN incoming_transactions USING (incoming_transaction_id)
- WHERE authorization_pub = in_authorization_pub
- ORDER BY execution_time ASC
- LIMIT 1
- )
- RETURNING incoming_transaction_id
+ -- Finalize one pending right now.
+ DELETE FROM pending_recurrent_incoming_transactions
+ WHERE incoming_transaction_id = (
+ SELECT incoming_transaction_id
+ FROM pending_recurrent_incoming_transactions
+ JOIN incoming_transactions USING (incoming_transaction_id)
+ WHERE authorization_pub = in_authorization_pub
+ ORDER BY execution_time ASC
+ LIMIT 1
)
- INSERT INTO talerable_incoming_transactions (incoming_transaction_id, type, metadata, authorization_pub, authorization_sig)
- SELECT moved_tx.incoming_transaction_id, in_type, in_account_pub, in_authorization_pub, in_authorization_sig
- FROM moved_tx
- RETURNING incoming_transaction_id, taler_in_id INTO talerable_tx, local_taler_in_id;
+ RETURNING incoming_transaction_id INTO talerable_tx;
IF talerable_tx IS NOT NULL THEN
- PERFORM pg_notify('nexus_incoming_tx', local_taler_in_id::text);
+ -- Lock for incoming history id commit ordering
+ LOCK TABLE talerable_incoming_transactions IN SHARE ROW EXCLUSIVE MODE;
+ INSERT INTO talerable_incoming_transactions (incoming_transaction_id, type, metadata, authorization_pub, authorization_sig)
+ VALUES (talerable_tx, in_type, in_account_pub, in_authorization_pub, in_authorization_sig)
+ RETURNING incoming_transaction_id, taler_in_id INTO talerable_tx, local_taler_in_id;
+ IF talerable_tx IS NOT NULL THEN
+ PERFORM pg_notify('nexus_incoming_tx', local_taler_in_id::text);
+ END IF;
END IF;
ELSE
-- Bounce all pending