Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring @Retryable with stateful Hibernate Object

I am trying to make my Service Method retrying on failure with Springs @Retryable.

@Retryable(backoff = @Backoff(delay = 1000), maxAttempts = 3)
@Transactional(rollbackFor = Throwable.class)
public Something saveSomething(Something something) {
  //some logic and saving
}

The Problem is, that the exception appears after saving the something-object. So the Transaction is rolled back and the Method is called again. The Difference is that the id of the something-object is not null anymore but the value it got from the previous saving process by Hibernate so in the second attempt Hibernate does not save the object but tries to update it. Since no entry is in the DB the update doesn't do anything and the object is not persited to the DB.

After recognizing this i tried to set the stateful property of @Retryable to true:

@Retryable(backoff = @Backoff(delay = 1000), maxAttempts = 3, stateful = true)
@Transactional(rollbackFor = Throwable.class)
public Something saveSomething(Something something) {
  //some logic and saving
}

But with that config saveSomething() is just called once and der is no second attempt.

Has anyone suggestions to solve this problem?

like image 419
Philipp Schweiger Avatar asked Oct 17 '22 07:10

Philipp Schweiger


1 Answers

When you use stateful retry; the caller has to call the method again for the next retry; the state maintains how many attempts have been made. So, you have to use try/catch and call saveSomething in a loop (with a new Something, or setting the id to null) until it succeeds - using an @Recover method for when retries are exhausted, where you can throw a different exception so the caller knows the difference between something that should be retried and when retries are exhausted.

like image 68
Gary Russell Avatar answered Nov 03 '22 23:11

Gary Russell