[英]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.