Spring returns CompletableFuture 的交易方法

Spring Transactional method which returns CompletableFuture

我有从服务调用方法的 RestController。方法将用户添加到最多 20 个连接的 PostresSQL 数据库。

@RestController
public class Controller {
    @RequestMapping(value = "/user", method = RequestMethod.POST)
    public String addUser(@RequestBody UserInfo userInfo) {
        Future<String> completableFuture = userService.addUser(userInfo);
        String answer = voidCompletableFuture.get();
        return answer;
    }
}

服务中的方法由 Spring Transactional 注释,在持久化数据方法 returns CompletableFuture 之后,其中有一些长时间的操作。我从多个线程(大约 100 个)同时调用方法“/user”。

@Transactional
public Future<String> addUser(UserInfo userInfo) {
    userDao.persist(userInfo);
    return CompletableFuture.supplyAsync(() -> {
        try {
            Thread.sleep(10000);
            return "Result";
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "Error";
    });
}

如果调用阻塞当前线程的代码行 "voidCompletableFuture.get()",则只有 20 个并发请求在工作,并按最大连接数向数据库添加数据。另一个线程中有异常:

Caused by: java.sql.SQLTransientConnectionException: Connection is not available, request timed out after 30000ms.

如果我删除这行代码,那么每个请求都会正常工作并按预期将数据添加到数据库中。我认为这是因为如果我在之后调用 future.get() ,则在方法 "public Future addUser(UserInfo userInfo)" 结束后事务未完成。 也许有人知道为什么 Spring 和 CompletableFuture 以这种方式工作,或者也许还有另一个答案?为什么阻塞 CompletableFuture 会影响另一种方法中事务的结束?如果请求方法中有块,为什么方法不完成当前事务并且不释放连接。

在添加 spring.jpa.open-in-view=false 方法后事务开始停止 setUser() 而不是在请求的整个过程中。

来自文档: spring.jpa.open-in-view=true - Register OpenEntityManagerInViewInterceptor. Binds a JPA EntityManager to the thread for the entire processing of the request.