Hi Sarthak ,
That’s a great observation — you’re definitely thinking in the right direction. The *DB unique constraint approach* we discussed is mainly intended to address the *concurrency problem* — preventing two identical requests from being processed at the same time due to race conditions. By relying on a unique constraint at the database level, we let the DB enforce this atomically, which avoids adding additional locking or coordination logic in the application layer. What you’re suggesting — storing request states like IN_PROGRESS, SUCCESS, or FAILED along with the response payload — is essentially an *idempotency + response replay mechanism*. This pattern is commonly used in APIs such as Stripe. It helps in situations where: - The server successfully processes the transaction - The client *never receives the response* (for example due to a timeout or network issue) - The client retries the same request In those cases, instead of returning a 409, the server could simply *return the previously stored successful response*, which improves the client experience. That said, introducing such a mechanism also brings a few additional considerations: 1. *Persistence overhead* We would need to store request identifiers, their status, and possibly the response payload in a dedicated table. 2. *Lifecycle management* These records would need some expiration or cleanup strategy so the table doesn’t grow indefinitely. 3. *Payload storage complexity* Storing full response payloads can introduce challenges around serialization, schema changes, and storage size. 4. *Architectural scope* Fineract currently leans more on *transactional guarantees at the database level*, so introducing a generalized idempotency layer would likely be a broader architectural enhancement rather than a minimal fix for this specific issue. So for *FINERACT-2485*, the DB constraint approach keeps the solution: - *Atomic* - *Simple* - *Low impact on the existing architecture* That said, your idea is definitely valid and aligns with how many modern APIs handle *retry-safe operations*. It could be interesting to explore it as a *separate enhancement proposal* if we ever want to introduce a more generalized idempotency mechanism in Fineract. Good question — thinking about retry scenarios like this is exactly how we end up designing more robust systems. On Sun, 22 Mar 2026 at 13:05, Sarthak Deokar <[email protected]> wrote: > Hi Deepak, > > This is about FINERACT-2485 > > Thanks for the detailed analysis, especially the concurrency issue around > simultaneous duplicate requests. The DB unique constraint approach for > atomic locking makes a lot of sense as a first line of defense. > > While exploring the same flow, I was also thinking about how to handle > post-execution retries from the client side (e.g., when the response is > lost after a successful transaction). > > In such cases, instead of returning a 409, would it make sense to extend > the design with a response replay mechanism (e.g., storing status like > IN_PROGRESS/SUCCESS/FAILED along with response payload)? > > This could allow: > > - > > Returning the same response for duplicate successful requests > - > > Handling in-progress requests more gracefully > - > > Improving client experience in unstable network conditions > > Do you think this could complement the DB constraint approach, or would it > introduce unnecessary complexity in the current architecture? > > Would love to hear your thoughts. >
