Now I have basic DAO interface for Entity object (contextual data actually doesn't matter):
public interface EntityDAO {
CompletableFuture<Void> create(Entity entity);
CompletableFuture<Optional<Entity>> get(String id);
CompletableFuture<Void> update(Entity entity);
CompletableFuture<Void> delete(Entity entity);
}
Imagine a situation when I needed to make thigs in this sequence:
- Retrieve existing entity.
- Do something operations with retrieved
Entity. - Save changes.
Considering there is a possibility of simultaneous access to the Entity object while executing the business logic at step 2, I need to acquire a lock for the duration of its execution (PESSIMISTIC_WRITE I guess).
So, since locks bounded to transactions I need to keep transaction between EntityDAO#get(String) and EntityDAO#update(Entity) calls as far as I understood. This approach doesn't look correct and also makes it impossible to call Entity#get(String) and EntityDAO#update(Entity) independently of each other.
One of the solutions I came to is create a new one method (like below) that would allow you to get data with a lock, allow you to perform an action on the object, write changes and release the lock:
CompletableFuture<Optional<Entity>> getAndSave(String id);
But I still don't think this approach is really the correct one.
So, my question is: How should I properly design a database access layer and buisness logic layer to achieve the above?
Thank you in advance for your answers!