springspring-bootspring-asyncjava-21virtual-threads

How to limit the number of Spring @Async tasks with virtual threads enabled


I have an @Async task executing some database related background work. After enabling virtual threads (spring.threads.virtual.enabled: true) the number of Async jobs executed in parallel is no longer limited. The result is an exhausted database connection pool. When virtual threads is disabled only 8 (default) jobs are executed in parallel so less database connections are used.

What would be the recommended approach to solve this problem?

org.apache.tomcat.jdbc.pool.PoolExhaustedException: [task-49889] Timeout: Pool empty. Unable to fetch a connection in 30 seconds, none available[size:100; busy:100; idle:0; lastwait:30000]

@Component
@RequiredArgsConstructor
public class TestTask {

    private final MyRepository myRepository;
    @Async
    public void execute() {
        // some database calls.
        myRepository.doSomething();
    }
}

When executing 200 tasks the pool is exhausted.

IntStream.range(1, 200).forEach(value -> testTask.execute());

I'm using Java 21 with Spring Boot 3.2.1.


Solution

  • You can configure concurrency in this case through the spring.task.execution.simple.concurrency-limit property. Default it isn't set and thus means unbounded.

    Setting it in your application properties.

    spring.task.execution.simple.concurrency-limit=8
    

    This will limit it to 8 concurrent tasks (or the number you choose it to be). The auto-configuration takes care of this.