Asynchronous @异步注释正在创建线程,但只有一个线程承担所有负载
我需要将巨大的负载持久化到数据库。所以我决定使用异步调用来持久化一批记录。我使用@EnableAsync注释启用了异步处理。我还在服务层的一个方法上使用了@Async,如下所示Asynchronous @异步注释正在创建线程,但只有一个线程承担所有负载,asynchronous,spring-data-jpa,Asynchronous,Spring Data Jpa,我需要将巨大的负载持久化到数据库。所以我决定使用异步调用来持久化一批记录。我使用@EnableAsync注释启用了异步处理。我还在服务层的一个方法上使用了@Async,如下所示 @Async @Transactional public CompletableFuture<Boolean> insertRecords(List<Record> records) { recordRepository.saveAll(records); recordRepos
@Async
@Transactional
public CompletableFuture<Boolean> insertRecords(List<Record> records) {
recordRepository.saveAll(records);
recordRepository.flush();
LOGGER.debug(Thread.currentThread().getName()+" -> inserting);
return CompletableFuture.completedFuture(Boolean.TRUE);
}
Above method is called from another service method
@Transactional
public void performSomeDB(InputStream is){
//perform another CRUD operation
processStream(is);
}
private void processStream(InputStream is){
//Read stream using JsonReader and load into a list
// record by record. Once the desired batch is met, pass the
// list to insertRecords
List<Record> records = new ArrayList<>();
List<CompletableFuture<Boolean>> statuses = new ArrayList<>();
while(stream has data){
records.add(record);
statuses.add(insertRecords(records);
}
System.out.println(statuses.size()); // It returns >1 based on the iterations.
在日志中,我只看到一个线程正在运行并按顺序保存一批记录
为什么只有一个线程承担了保存所有记录的负载
我的方法不正确吗?这就是异步的魔力和一般思想。它在不生成多个线程的情况下共享全部负载。如果使用Spring的Java配置,您的配置类需要实现AsyncConfigurer:
@Configuration
@EnableAsync
public class AppConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(50);
executor.setThreadNamePrefix("MyPool");
executor.initialize();
return executor;
}
}
您可以参考下面的文档了解更多详细信息:至于@Async注释,自调用–从同一个类中调用异步方法–将不起作用。 您应该在一个单独的类中创建该方法,并使用该类的bean对象引用它
@Component
public class DbInserter {
@Async
@Transactional
public CompletableFuture<Boolean> insertRecords(List<Record> records) {
recordRepository.saveAll(records);
recordRepository.flush();
LOGGER.debug(Thread.currentThread().getName()+" -> inserting);
return CompletableFuture.completedFuture(Boolean.TRUE);
}
}
@组件
公共类数据库插入器{
@异步的
@交易的
公共完整未来插入记录(列表记录){
recordRepository.saveAll(记录);
recordRepository.flush();
LOGGER.debug(Thread.currentThread().getName()+“->插入);
返回CompletableFuture.completedFuture(Boolean.TRUE);
}
}
应用程序中的瓶颈似乎是数据库。如果这是真的,那么用更多的请求并行地访问它可能不会有帮助。尤其是当所有请求都访问同一个表和索引时,这只会创建锁争用。
@Component
public class DbInserter {
@Async
@Transactional
public CompletableFuture<Boolean> insertRecords(List<Record> records) {
recordRepository.saveAll(records);
recordRepository.flush();
LOGGER.debug(Thread.currentThread().getName()+" -> inserting);
return CompletableFuture.completedFuture(Boolean.TRUE);
}
}