Spring, JPA, and Hibernate - how to increment a counter without concurrency issues
The simplest solution is to delegate the concurrency to your database and simply rely on the database isolation level lock on the currently modified rows:
The increment is as simple as this:
UPDATE Tag t set t.count = t.count + 1 WHERE t.id = :id;
and the decrement query is:
UPDATE Tag t set t.count = t.count - 1 WHERE t.id = :id;
The UPDATE query takes a lock on the modified rows, preventing other transactions from modifying the same row before the current transaction commits (as long as you don't use READ_UNCOMMITTED
).