Conversation
Member
Author
|
Fixes #525 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why is this change proposed?
When
withCommandBusRetryis enabled and a command is dispatched via CommandBus from inside an async handler withwithTransactionOnAsynchronousEndpoints(true), the InstantRetry interceptor retries inside the already-active transaction. On PostgreSQL, after a SQL error the transaction enters "aborted" state — all subsequent SQL statements fail with "current transaction is aborted, commands ignored until end of transaction block". This makes all retry attempts useless, as they execute inside the same broken transaction.Resolves #525
Description of Changes
TransactionStatusTrackerin core (Ecotone\Modelling\Config\DatabaseTransaction), following the same pattern asRetryStatusTrackerDbalTransactionInterceptormarks the tracker when it starts a transaction, unmarks after commit/rollbackInstantRetryInterceptorchecks the tracker and skips retry if already inside a transactionHow it works
When
withCommandBusRetryruns inside an async endpoint transaction, InstantRetry now detects the active transaction and skips — letting the exception propagate up to the async endpoint level. Users should usewithAsynchronousEndpointsRetryfor async endpoints, which wraps the transaction and retries on fresh state.sequenceDiagram participant AsyncRetry as InstantRetry (async, -2002) participant Txn as DbalTransaction (-2000) participant Handler as Async Handler participant CB as CommandBus participant CmdRetry as InstantRetry (commandBus) participant CmdHandler as Command Handler AsyncRetry->>Txn: proceed() Txn->>Txn: BEGIN TRANSACTION Txn->>Handler: proceed() Handler->>CB: sendWithRouting() CB->>CmdRetry: proceed() Note over CmdRetry: isInsideTransaction() = true → skip CmdRetry->>CmdHandler: proceed() CmdHandler--xCmdRetry: SQL Error CmdRetry--xCB: rethrow (no retry) CB--xHandler: rethrow Handler--xTxn: rethrow Txn->>Txn: ROLLBACK Txn--xAsyncRetry: rethrow AsyncRetry->>Txn: retry with fresh state Txn->>Txn: BEGIN TRANSACTION (fresh) Txn->>Handler: proceed() Handler->>CB: sendWithRouting() CB->>CmdRetry: proceed() CmdRetry->>CmdHandler: proceed() CmdHandler-->>AsyncRetry: success Txn->>Txn: COMMITConfiguration
Pull Request Contribution Terms