Java 返回CompletableFuture的Spring事务方法
我有一个从服务调用方法的RestController。方法将用户添加到PostresSQL数据库,该数据库最多有20个连接Java 返回CompletableFuture的Spring事务方法,java,spring,transactional,spring-restcontroller,completable-future,Java,Spring,Transactional,Spring Restcontroller,Completable Future,我有一个从服务调用方法的RestController。方法将用户添加到PostresSQL数据库,该数据库最多有20个连接 @RestController public class Controller { @RequestMapping(value = "/user", method = RequestMethod.POST) public String addUser(@RequestBody UserInfo userInfo) { Future<St
@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;
}
}
若我删除这行代码,那个么每个请求都会正常工作,并按预期将数据添加到数据库中。我认为这是因为如果我在“public Future addUser(UserInfo UserInfo)”方法结束后调用Future.get()时,事务没有完成。
也许有人知道为什么Spring和CompletableFuture会以这种方式工作,或者也许还有另一个答案?为什么阻止CompletableFuture会影响另一种方法中的事务结束?如果请求方法内部有块,为什么方法不完成当前事务并且不释放连接。在添加
spring.jpa.open in view=false之后
事务在方法setUser()
之后开始停止,而不是在请求的整个过程中
从文件:
spring.jpa.openin-view=true-注册OpenEntityManagerInViewInterceptor。在整个请求处理过程中将JPA EntityManager绑定到线程。
有没有可能您的事务已经在调用addUser()
的地方启动,并且在调用get()
方法之前没有提交?@DidierL我查看了事务日志,事务在addUser()
中开始,然后只有几个事务在调用get()
方法之前完成。然后,当get()
阻止请求时,事务停止完成(日志TransactionInterceptor:485:完成事务
)。然后连接数超过数据源中连接池中的最大值,然后发生此异常,原因是:java.sql.SQLTransientConnectionException:连接不可用
。不知道为什么连接会停止以完成。看起来我的评论让您找到了正确的方向;-)TBH,我认为OpenInView现在已经被弃用了,因为它可能会导致一些类似这样的问题(包括其他性能问题)。然而,在现有应用程序中更改它可能会产生副作用。
@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";
});
}
Caused by: java.sql.SQLTransientConnectionException: Connection is not available, request timed out after 30000ms.