I'm using Java 8 with Spring Boot. How can I achieve retry logic for the following scenario?
- I will generate a random key for a DB.
- Query the DB for that key, if present, retry with a new key.
- Persist the data with a newly generated key.
example code:
int attempts = 1;
while (attempts <= PRESCRIBED_ATTEMPTS) {
String key = generateSomeRandomAlphaNum();
Future<String> resultFromDb = someRepository.getById(key);
resultFromDb.onSuccess(
result -> {
// since the key is already present
// retry here
Future<String> newAttempt = someRepository.getById(key);
attempts ;
}
);
}
I'm using Couchbase, so the key here is basically a reference document.
CodePudding user response:
Your approach is incorrect. The primary key generation is the responsibility of DB and not yours. So when you want to insert new object your Entity should be just properly annotated in such a way that DB will generate guaranteed unique ID for you. To see how its done see this article: An Overview of Identifiers in Hibernate/JPA. However, in general if you want to generate some unique ID for whatever purpose by yourself then you should create your own generator that will be responsible to create unique ids. If you need to provide unique id within your running program scope then the simples one would be to use AtomicLong class and just increment it each time you need a new ID. If you want to create world-wide unique ID then use UUID class
CodePudding user response:
I made following static test with just a minor change. Most important is the while loop. Pay Attention that you initialize attempts with 0 and not 1. Recommended is camelcase notation ( PRESCRIBED_ATTEMPTS-> prescribedAttempts)
Note: This solution is synchron, you could make this function asynchron by implementing a future callback
public class DemoApplication {
private static int random = 0;
public static int generateSomeRandomAlphaNum() {
return random ;
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication2.class, args);
int attempts = 0; // 0 because you didnt had an attempt yet. 1 predicts you had one already.
int predscribedAttempts= 10;
int key = generateSomeRandomAlphaNum();
System.out.println("key: " key);
while (key != 7 && attempts <= predscribedAttempts) {
key = generateSomeRandomAlphaNum();
System.out.println("key: " key);
attempts ;
}
//finished within x attempts
System.out.println("finished within " attempts " attempts");
}
}
With your code it would look like:
public static void main(String[] args) {
SpringApplication.run(DemoApplication2.class, args);
int attempts = 0;
int predscribedAttempts= 10;
Future<String> resultFromDb = someRepository.getById(key);
while (!resultFromDb.isEmpty() && attempts <= predscribedAttempts) {
resultFromDb = someRepository.getById(key);
attempts ;
}
//finished
}
CodePudding user response:
Suggest to use resilience4j library in order to adhere to DRY principles. Resilience4j one of many modules is "Retry" which is a mechanism to automatically retry a failed mechanism. Hope this https://reflectoring.io/retry-with-resilience4j/ will help you.