You can use locking for that. The appropriate type of locking depends on your use case.
If the probability of a concurrent update is low, use optimistic locking. In case of an update collision, catch the Exception
, refresh the entity, reapply your changes and retry the commit.
If you use optimistic locking, it is advised to add a @Version
field to your entity. Optimistic locking without a version field is not guaranteed to be supported.
If the probability of a concurrent modification is high, use pessimistic locking. Thus you can serialize writes on the row. Note that this type of locking can create a bottleneck as transactions queue for updates and other transactions time out before acquiring the lock.
In order to minimize the lokc time, you can apply the lock on an individual query:
query.setLockMode(LockMode.WRITE)
EDIT: The locks can be probably used in a distributed environment safely.
Optimistic locking is implemented as a check on the @Version
field in the DB at commit time (or equivalent) - with read-commited isolation (the default) there is no risk of missing a committed change to the entity.
Pessimistic locking is implemented on DB level, often using SELECT FOR UPDATE
or similar. So you don't have to worry.