我已经使用Spring Boot创建了Web服务,并且其中有一个rest控制器,该控制器通过基于供应商的JDBC驱动程序访问数据库并获取记录。在此过程中,检索到的记录数超过80K条记录。因此,无论何时我们以客户端身份访问其余端点,我们都会遇到超时错误。
我尝试使用下面的教程设置异步调用。但是不幸的是,其余调用仍在超时。
https://howtodoinjava.com/spring-boot2/enableasync-async-controller/
控制器
@RequestMapping(value = "/v1/lr/fullpositionasync", produces = {APPLICATION_JSON_UTF8_VALUE}, method = RequestMethod.GET)
@ResponseBody
public CompletableFuture<List<Position>> retrieveTradePositionsFullAsync(HttpServletRequest request, HttpServletResponse response) throws ExecutionException, InterruptedException {
CompletableFuture<List<Position>> positionList =null;
try {
positionList = positionService.getFullPosition();
}
catch(Exception e){
log.info("Error Occurred in Controller is:"+e.getMessage());
}
CompletableFuture.allOf(positionList).join();
log.info(String.valueOf(positionList.get()));
return positionList;
}
服务
@Service
@Slf4j
public class PositionServiceImpl implements PositionService {
@Autowired
private PositionDao positionDao;
@Async("asyncExecutor")
@Override
public CompletableFuture<List<Position>> getFullPosition() {
List<Position> fullpositionList = null;
log.info("Getting the full Position process started");
fullpositionList = positionDao.retrieveData();
log.info("Total Positions retrieved:"+fullpositionList.size());
try {
log.info("Thread is about to sleep 1000 milliseconds");
Thread.sleep(1000);
}catch(InterruptedException e){
log.info(e.getMessage());
}
log.info("Full Positions retrieval completed");
return CompletableFuture.completedFuture(fullpositionList);
}
}
配置
@Configuration
@EnableAsync
@Slf4j
public class AsyncConfiguration
{
@Bean(name = "asyncExecutor")
public Executor asyncExecutor()
{
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(20);
executor.setMaxPoolSize(1000);
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setThreadNamePrefix("AsynchThreadForEndPoint-");
executor.initialize();
log.info("Executor is :"+executor.toString());
return executor;
}
}
DAO
@Repository
public class PositionDaoImpl implements PositionDao {
@Autowired
private JdbcTemplate jdbcTemplate;
private static final String ALL_POSITION_QUERY = "call AllPositionProcedure()";
public List<Position> retrieveData() {
return jdbcTemplate.query(ALL_POSITION_QUERY, new BeanPropertyRowMapper(Position.class));
// List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sql);
}
答案 0 :(得分:0)
您不能使用JDBC在数据库上执行异步操作。 JDBC正在阻塞,因此它将阻塞您的线程,直到执行操作为止。如果要以异步方式执行操作,请使用R2DBC而不是JDBC。
答案 1 :(得分:0)
对于您的用例,最好的方法是将您的应用程序转换为反应式流(Flux)。
Flux是Reactive Streams发布者。它是JVM的完全无阻塞的反应式编程基础,具有高效的需求管理(以管理“背压”的形式)。它直接与Java 8功能API集成在一起,尤其是CompletableFuture,Stream和Duration。它提供可组合的异步序列API Flux(用于[N]个元素)和Mono(用于[0 | 1]个元素),从而广泛实现了Reactive Streams规范。
在现有应用中实施非常简单。只需更改您的存储库返回类型Flux而不是List或Future。
有关更多信息,您可以参考Here