fix(integrations): per-transaction savepoint in Plaid sync_transactions

new_bank_transaction inserts+submits Bank Transactions in a loop within one transaction. On a failed
insert/submit, Postgres poisons the transaction so the except's log_error dies with InFailedSqlTransaction;
MariaDB keeps the Bank Transactions synced before the failure. A full rollback would discard those on
MariaDB too, so wrap each iteration in a savepoint + rollback(save_point=) and re-raise -- preserves
MariaDB's partial-sync behaviour and heals the Postgres txn. The sibling handlers add_institution /
add_bank_accounts were already fixed; this closes the third.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Mihir Kandoi
2026-07-01 11:55:41 +05:30
parent b926b846b1
commit c58a4026a7

View File

@@ -215,7 +215,14 @@ def sync_transactions(bank, bank_account):
result = []
if transactions:
for transaction in reversed(transactions):
result += new_bank_transaction(transaction)
# per-transaction savepoint: a failed insert/submit must not discard the Bank
# Transactions already synced this run (MariaDB keeps them) nor poison the txn on Postgres
frappe.db.savepoint("plaid_sync_txn")
try:
result += new_bank_transaction(transaction)
except Exception:
frappe.db.rollback(save_point="plaid_sync_txn")
raise
if result:
last_transaction_date = frappe.db.get_value("Bank Transaction", result.pop(), "date")