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.
我有从服务调用方法的 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.