简体   繁体   English

返回 CompletableFuture 的 Spring Transactional 方法

[英]Spring Transactional method which returns CompletableFuture

I have RestController which calls method from service.我有 RestController 从服务调用方法。 Method adds User to PostresSQL database, which has maximum of 20 connections.方法将 User 添加到 PostresSQL 数据库,该数据库最多有 20 个连接。

@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;
    }
}

Method in service is annotated by Spring Transactional, after persisting data method returns CompletableFuture, inside of it some long operation.服务中的方法由Spring Transactional注解,持久化数据后方法返回CompletableFuture,里面有一些长操作。 I call method "/user" simultaneously from multiple threads (about 100).我从多个线程(大约 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";
    });
}

If line of code "voidCompletableFuture.get()", which blocking current thread, is called then only 20 simultaneous request is working and adding data to database by number of maximum connections.如果调用阻塞当前线程的代码行“voidCompletableFuture.get()”,则只有 20 个并发请求在工作,并按最大连接数向数据库添加数据。 There is exception in another threads:另一个线程中有异常:

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

If I remove this line of code, then every request is working and adds data to database as expected.如果我删除这行代码,那么每个请求都会正常工作并按预期向数据库添加数据。 I think it is because Transaction not completed after end of method "public Future addUser(UserInfo userInfo)" if I call future.get() after.我认为这是因为如果我在调用 future.get() 之后方法“public Future addUser(UserInfo userInfo)”结束后事务没有完成。 Maybe someone knows why Spring and CompletableFuture works in such a way or maybe there is another answer?也许有人知道为什么 Spring 和 CompletableFuture 以这种方式工作,或者也许还有另一个答案? Why blocking of CompletableFuture affects end of Transaction in another method?为什么在另一种方法中阻塞 CompletableFuture 会影响事务的结束? Why method not completing current transaction and not releasing connection if there is a block inside request method.如果请求方法中有一个块,为什么方法不完成当前事务并且不释放连接。

After adding spring.jpa.open-in-view=false transaction begin to stop after method setUser() and not in entire process of the request.添加spring.jpa.open-in-view=false事务开始在方法setUser()之后停止,而不是在请求的整个过程中。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM