Ralph Hopman created FINERACT-2570:
--------------------------------------

             Summary: 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


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)

Reply via email to