I'm trying to implement @Retryable
and @Recover
feature for my Database operation.
See below my sample code
@Retryable(value = {PriceUploadServiceException.class,RuntimeException.class}, maxAttempts = 3, backoff = @Backoff(10000))
@Transactional(value ="phoenixTxManager", propagation =Propagation.REQUIRED, rollbackForClassName ="PriceUploadServiceException")
public void insertUploadedData(UploadInsertReqDTO uploadInsertReq)
{
//Doing some insertion and update operation
}
@Modifying
@Transactional(value ="phoenixTxManager", propagation =Propagation.REQUIRED, rollbackForClassName ="PriceUploadServiceException")
@Recover
public void updatefailureStatus(RuntimeException ex,UploadInsertReqDTO uploadInsertReq)
{
//Doing some delete operation, If all the retry attempts got failed
logger.info("All Retry fails So Recover Invoked : "+uploadInsertReq.getSeqId());
Optional<AsyncProcessEntity> optAsync = asyncProcessRepo.findById(uploadInsertReq.getSeqId());
if(optAsync.isPresent())
{
AsyncProcessEntity asynObj = optAsync.get();
asyncProcessRepo.deleteById(asynObj.getAsyncProcessSeqId());
asynObj.setProcessStatus(AppConstants.FAILED);
phenixtEntityManager.persist(asynObj);
phenixtEntityManager.flush();
}
}
I have tried above logic in my code, that retry attempts working fine, But when I do delete and insert the records in @Recover
method, I'm getting below exception. Even I removed @Transactional
for @Recover
method
javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298)
at com.sun.proxy.$Proxy193.persist(Unknown Source)
at com.tcs.opt.priceupload.service.PriceUploadService.updatefailureStatus(PriceUploadService.java:339)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282)
at org.springframework.retry.annotation.RecoverAnnotationRecoveryHandler.recover(RecoverAnnotationRecoveryHandler.java:73)
at org.springframework.retry.interceptor.RetryOperationsInterceptor$ItemRecovererCallback.recover(RetryOperationsInterceptor.java:141)
at org.springframework.retry.support.RetryTemplate.handleRetryExhausted(RetryTemplate.java:512)
at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:351)
at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:180)
at org.springframework.retry.interceptor.RetryOperationsInterceptor.invoke(RetryOperationsInterceptor.java:115)
Please help me to resolve this issue, or else tell me any other solution to achieve this functionality.