I am interacting with the SAP Business One Service Layer using code generated via the SAP Cloud SDK.
One thing that must be accounted for with the Service Layer is the potential for deadlocks in the database. The general recommendation is to retry the operation if a deadlock is detected.
I am wondering if there is a way to elegantly wrap all calls made by the SAP Cloud SDK with a resilience decorator to retry in the case of a deadlock.
The current logic for checking for a deadlock is to check the ODataCode:
public boolean checkIfDeadlockError(Throwable serviceLayerThrowable){
if (serviceLayerThrowable instanceof ODataServiceErrorException serviceErrorException) {
return serviceErrorException.getOdataError().getODataCode().equals("-2038");
}
return false;
}
Right now I am having to ensure I wrap every single call with the same resilience decorator, which is tedious.
The SAP Cloud SDK allows you to specify a
retryOnExceptionPredicate(Predicate<Throwable> retryOnExceptionPredicate)
with the RetryConfiguration. With that you can specify in which cases an exception should be retried.
For example, you could do an instanceof
check like so: var predicate = e -> e instanceof IllegalArgumentException
.
Alternatively, you could catch the relevant exception within your code and return some other representation of the result.