Let's say I have a java class with a method like this (just an example)
@Transactional
public synchronized void onRequest(Request request) {
if (request.shouldAddBook()) {
if (database.getByName(request.getBook().getName()) == null) {
database.add(request.getBook());
} else {
throw new Exception("Cannot add book - book already exist");
}
} else if (request.shouldRemoveBook()) {
if (database.getByName(request.getBook().getName()) != null) {
removeBook();
} else {
throw new Exception("Cannot remove book - book doesn't exist");
}
}
}
Say this book gets removed and then re-added with a new author or other minor change, so this method might get called twice very fast from another system, first to remove the Book, then to add the same Book back (with some new details).
To handle this we might try (like I did) to add the above @Transactional code, and then also 'synchronized' when the @Transactional doesn't work. But strangely it fails on the second call with
"Cannot add book - book already exist".
I spent a lot of time trying to figure this out, so thought I'd share the answer.
synchronized
. – YoulandayoultononRequest
. – Incorrect