[
https://issues.apache.org/jira/browse/FINERACT-2570?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Ralph Hopman resolved FINERACT-2570.
------------------------------------
Resolution: Fixed
> Defer webhook/hook event publication to after transaction commit in batch
> requests with enclosingTransaction=true
> -----------------------------------------------------------------------------------------------------------------
>
> Key: FINERACT-2570
> URL: https://issues.apache.org/jira/browse/FINERACT-2570
> Project: Apache Fineract
> Issue Type: Bug
> Affects Versions: 1.14.0
> Reporter: Ralph Hopman
> Assignee: Ralph Hopman
> Priority: Major
>
> When a batch request uses {{{}enclosingTransaction: true{}}}, Fineract fires
> hook events (webhooks) _inside_ the database transaction, before the batch
> has fully committed. If a later request in the batch fails, the entire batch
> is rolled back, but the webhook for the earlier (now rolled-back) request has
> already been dispatched.
> This causes downstream systems that rely on webhooks (e.g. SMS notifications)
> to act on events that never actually persisted.
> h2. Root cause
> In {{{}SynchronousCommandProcessingService.executeCommand(){}}}, the call to
> {{publishHookEvent()}} happens synchronously at the end of each individual
> command execution, while the enclosing database transaction is still open.
> There is an existing TODO comment acknowledging this:
> {code:java}
> publishHookEvent(wrapper.entityName(), wrapper.actionName(), command,
> result); // TODO must be performed in a new transaction
> {code}
> h2. Proposed solution
> When running inside an enclosing batch transaction
> ({{{}BatchRequestContextHolder.isEnclosingTransaction() == true{}}}), defer
> the hook event publication by registering it as a
> {{TransactionSynchronization.afterCommit()}} callback instead of publishing
> immediately.
> * If the batch commits successfully, {{afterCommit()}} fires and all hook
> events are published.
> * If the batch rolls back, {{afterCommit()}} is never called. No spurious
> webhooks are dispatched.
> * When _not_ in an enclosing transaction (the common single-request case),
> behavior is unchanged. Hooks fire immediately as before.
> * Error hooks ({{{}publishHookErrorEvent{}}}) remain immediate. The command
> failed, and error webhooks should still fire regardless of batch outcome.
> h2. Tests
> Two new unit tests should be added to
> {{{}SynchronousCommandProcessingServiceTest{}}}:
> * Verify that when {{BatchRequestContextHolder.isEnclosingTransaction()}} is
> true and transaction synchronization is active,
> {{applicationContext.publishEvent()}} is not called immediately and a
> {{TransactionSynchronization}} callback is registered instead.
> * Verify that existing non-batch behavior is preserved (hooks fire
> immediately).
> h2. Impact
> * Fixes false-positive webhook notifications (SMS, email) for transactions
> that are subsequently rolled back within a batch.
> * No impact on non-batch (single request) command processing (behavior is
> identical to today).
> * No impact on error hook events (they continue to fire immediately).
--
This message was sent by Atlassian Jira
(v8.20.10#820010)