重试逻辑以检查数据库中的现有密钥

发布于 2025-01-11 00:28:40 字数 603 浏览 0 评论 0原文

我正在使用 Java 8 和 Spring Boot。如何实现以下场景的重试逻辑?

  1. 我将为数据库生成一个随机密钥。
  2. 在数据库中查询该密钥(如果存在),然后使用新密钥重试。
  3. 使用新生成的密钥保留数据。

示例代码:

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++;
    }
  );
}

我使用的是Couchbase,所以这里的关键基本上是参考文档。

I'm using Java 8 with Spring Boot. How can I achieve retry logic for the following scenario?

  1. I will generate a random key for a DB.
  2. Query the DB for that key, if present, retry with a new key.
  3. 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

青瓷清茶倾城歌 2025-01-18 00:28:40

我做了以下静态测试,只做了一个小小的改变。
最重要的是 while 循环。
请注意,您使用 0 而不是 1 来初始化尝试。
推荐使用驼峰命名法( PRESCRIBED_ATTEMPTS->specifiedAttempts )

注意:这个解决方案是同步的,您可以通过实现未来的回调来使该函数异步

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");
    }

}

使用您的代码,它看起来像:

 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
    }

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
    }
拥有 2025-01-18 00:28:40

你的做法是不正确的。主键生成是数据库的责任,而不是您的责任。因此,当您想要插入新对象时,您的实体应该以这样的方式正确注释,以便数据库将为您生成有保证的唯一 ID。要了解它是如何完成的,请参阅这篇文章:Hibernate/JPA 中标识符概述。然而,一般来说,如果您想自己出于任何目的生成一些唯一的 ID,那么您应该创建自己的生成器来负责创建唯一的 ID。如果您需要在正在运行的程序范围内提供唯一的 id,那么最简单的方法是使用 AtomicLong 类,并在每次需要新 ID 时递增它。如果您想创建全球唯一 ID,请使用 UUID

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

烂人 2025-01-18 00:28:40

建议使用resilience4j库以遵守DRY原则。 Resilience4j 的众多模块之一是“重试”,这是一种自动重试失败机制的机制。希望这个 https://reflectoring.io/retry-with-resilience4j/ 会对您有所帮助。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文