How should a Spring Boot app handle two users editing the same invoice?

0
4
Asked By MellowCedar42 On

I'm building an invoicing system with Spring Boot and Angular, and I'm trying to handle concurrent edits to the same invoice. If one user exports invoices while another creates a new one, normal database transactions handle that fine. The real problem is when two users open invoice #12, make different changes, and save. Without extra protection, the second save silently overwrites the first user's changes.

I've already tried optimistic locking with a JPA/Hibernate @Version column, which detects a stale version and rejects the update. I've also considered pessimistic locking with SELECT FOR UPDATE for cases where a record truly needs to be locked. Optimistic locking seems like the usual choice for CRUD applications, but I'm unsure about the best user experience when a conflict occurs.

Should the application simply reject the save and make the user reload? Should it compare and merge field-level changes? Is it worth showing an indicator that another user is currently editing the invoice? I'm also interested in how modern web applications handle the same disconnected-snapshot and comparison behavior that older desktop data tools provided.

3 Answers

Answered By VersionPine19 On

The core terms to look into are optimistic concurrency control, row versioning, and pessimistic locking. A version or timestamp column is often all you need: the update includes the ID and version that was originally loaded, for example, and succeeds only if both still match. Check the affected-row count as well, since zero updated rows means the data became stale.

Pessimistic locks can work, but they’re usually a poor fit for a web form because users may leave a page open for minutes. Holding a database lock for that entire time hurts concurrency and can create timeouts. Use them for short, critical transactions rather than for the period between opening and submitting a form.

AmberLoft63 -

That makes sense. A short transaction-level lock is very different from locking the invoice just because someone opened the edit page.

Answered By CobaltMeadow8 On

A useful UX is to detect conflicts at save time, reload the latest server state, and highlight the fields that changed. Keep the user’s draft on the page so their work isn’t lost, then give them options such as keep mine, use the latest value, or review the differences.

You can also show a lightweight “edited by someone else” indicator using a last-modified timestamp or presence information, but treat that as a warning only. It can’t replace optimistic locking because another user may save immediately after the indicator is checked. The database-side version check remains the authority.

Answered By QuietHarbor7 On

Optimistic locking is usually the right default when simultaneous edits are uncommon. Store the version the client loaded and require it to match the current database version during the update. If it doesn’t match, return a conflict response instead of overwriting the newer data.

The UI can then fetch the current record, preserve the user’s unsaved values, and show a comparison between their version and the server version. For simple forms, you can let them choose which values to keep or retry non-conflicting field changes. For a small edit, a clear “this invoice changed while you were editing” message may be enough. Full operational transformation or CRDTs are generally only necessary for collaborative, real-time editing such as shared documents.

MellowCedar42 -

So the backend pattern is basically version checking plus a conflict response, and the merge or reload experience is handled by the UI?

Related Questions

LEAVE A REPLY

Please enter your comment!
Please enter your name here

This site uses Akismet to reduce spam. Learn how your comment data is processed.