进行一个异步调用,需要将ID存储到数据库而不阻塞。

huangapple go评论103阅读模式
英文:

Make an Asynch call that needs to store ids to database without blocking

问题

我正在使用Spring的@Asynch注解。我有一个场景,需要进行两个API调用。其中一个API调用通过@Async打开了一个新线程,因为调用方不关心这个API调用,只关心第一个API调用。然而,这两个API调用都会返回我想要存储到数据库中的ID。我该如何完成这个任务?由于数据库的存储依赖于这两个ID,它将阻止我打开新线程的意图。

  1. public class SecondAPICallService {
  2. @Async
  3. public CompletableFuture<String> makeSecondApiCall(String firstAPICallId) {
  4. var secondAPICallId = webClient.post(firstAPICallId, ...);
  5. return CompletableFuture.completedFuture(secondAPICallId);
  6. }
  7. }
  8. public class FirstAPICallService {
  9. @Autowired
  10. SecondAPICallService secondAPICallService;
  11. @Autowired
  12. DatabaseService dbService;
  13. public Response makeApiCall(String firstAPICallId) {
  14. Response response = webClient.post(..);
  15. String id = response.getId();
  16. CompletableFuture<String> secondAPICallId = secondAPICallService.makeSecondApiCall(id);
  17. // 这里使用.get()会阻塞线程,但我不确定该怎么办,因为我需要存储到数据库中
  18. String secondId = secondAPICallId.get();
  19. dbService.save(id, secondId);
  20. return response;
  21. }
  22. }
  1. @Configuration
  2. @EnableAsync
  3. public class AsyncConfiguration {
  4. @Bean(name = "asyncExecutor")
  5. public Executor asyncExecutor() {
  6. ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  7. executor.setCorePoolSize(3);
  8. executor.setMaxPoolSize(3);
  9. executor.setQueueCapacity(100);
  10. executor.setThreadNamePrefix("AsyncThread-");
  11. executor.initialize();
  12. return executor;
  13. }
  14. }

希望这对你有帮助。

英文:

I am using Spring @Asynch. I have a scenrio where I have to make two API calls. One API call opens a new thread via @Async since the caller doesn't care about this API call and only cares about the first API call. However, both these API calls return back ids that I want to store into the database. How will I go about accomplishing this? Since the storing of the database depends on both the ids it will block my intent of opening a new thread.

  1. public class SecondAPICallService {
  2. @Asynch
  3. public CompletableFuture&lt;String&gt; makeSecondApiCall(String firstAPICallId) {
  4. var secondAPICallId = webClient.post(firstAPICallId, ...);
  5. return CompletableFuture.completedFuture(secondAPICallId);
  6. }
  7. }
  8. public class FirstAPICallService {
  9. @Autowire
  10. SecondAPICallService secondAPICallService;
  11. @Autowire
  12. DatabaseService dbService;
  13. public Response makeApiCall(String firstAPICallId) {
  14. Response response = webClient.post(..);
  15. String id = response.getId();
  16. CompletableFuture&lt;String&gt; secondAPICallId = secondAPICallService.makeSecondApiCall(id);
  17. // This here blocks my thread with .get but not sure what to do since I need to store in db
  18. String secondId = secondAPICallId.get();
  19. dbService.save(id, secondId);
  20. return response;
  21. }
  22. }

  1. @Configuration
  2. @EnableAsync
  3. public class AsyncConfiguration {
  4. @Bean(name = &quot;asyncExecutor&quot;)
  5. public Executor asyncExecutor() {
  6. ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  7. executor.setCorePoolSize(3);
  8. executor.setMaxPoolSize(3);
  9. executor.setQueueCapacity(100);
  10. executor.setThreadNamePrefix(&quot;AsynchThread-&quot;);
  11. executor.initialize();
  12. return executor;
  13. }
  14. }

答案1

得分: 1

  1. public class SecondAPICallService {
  2. @Async
  3. public CompletableFuture<String> makeSecondApiCall(String firstAPICallId) {
  4. // 进行第二次API调用
  5. CompletableFuture<String> future = new CompletableFuture<>();
  6. // 异步执行第二次API调用
  7. // 一旦获取到第二次API调用的ID,使用该ID来完成CompletableFuture
  8. // 例如:
  9. String secondId = // 获取第二次API调用的ID
  10. future.complete(secondId);
  11. return future;
  12. }
  13. }
  14. public class FirstAPICallService {
  15. @Autowired
  16. SecondAPICallService secondAPICallService;
  17. @Autowired
  18. DatabaseService dbService;
  19. public Response makeApiCall(String firstAPICallId) {
  20. Response response = webClient.post(..);
  21. String id = response.getId();
  22. // 异步执行第二次API调用
  23. CompletableFuture<String> secondAPICallId = secondAPICallService.makeSecondApiCall(id);
  24. // 注册一个回调函数,以在第二次API调用完成时执行
  25. secondAPICallId.thenAcceptAsync(secondId -> {
  26. // 将ID保存到数据库
  27. dbService.save(id, secondId);
  28. });
  29. return response;
  30. }
  31. }
英文:
  1. @Async
  2. public CompletableFuture&lt;String&gt; makeSecondApiCall(String firstAPICallId) {
  3. // Make the second API call
  4. CompletableFuture&lt;String&gt; future = new CompletableFuture&lt;&gt;();
  5. // Perform the second API call asynchronously
  6. // Once you obtain the second API call ID, complete the CompletableFuture
  7. // with the second API call ID value
  8. // For example:
  9. String secondId = // Obtain the second API call ID
  10. future.complete(secondId);
  11. return future;
  12. }
  13. }
  14. public class FirstAPICallService {
  15. @Autowired
  16. SecondAPICallService secondAPICallService;
  17. @Autowired
  18. DatabaseService dbService;
  19. public Response makeApiCall(String firstAPICallId) {
  20. Response response = webClient.post(..);
  21. String id = response.getId();
  22. // Perform the second API call asynchronously
  23. CompletableFuture&lt;String&gt; secondAPICallId = secondAPICallService.makeSecondApiCall(id);
  24. // Register a callback function to be executed when the second API call completes
  25. secondAPICallId.thenAcceptAsync(secondId -&gt; {
  26. // Save the IDs to the database
  27. dbService.save(id, secondId);
  28. });
  29. return response;
  30. }
  31. }

huangapple
  • 本文由 发表于 2023年7月13日 21:53:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76680173.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定