[英]Java Play 2.3 F.Promise No Entity Manager bound to this thread
我正在嘗試同時訪問mysql數據庫以使用F.Promise獲取對象列表,但是我得到了:
沒有實體管理器綁定到此線程
盡管在方法內部調用了存儲過程,但我使用JPA.withTransactionAsync對其進行了包裝,但仍然收到相同的錯誤。
import play.libs.F.*;
import play.mvc.*;
import java.util.concurrent.Callable;
import static play.libs.F.Promise.promise;
public class Application extends Controller {
public static Promise<Result> index() {
return promise(new Function0<Integer>() {
public Integer apply() {
return getUserId();
}
}).map(new Function<Integer,Result>() {
public Result apply(Integer i) {
return ok("Got " + i);
}
});
在getUserId()內部
public static int getUserId()
{
return JPA.withTransactionAsync(.........);
}
這是一個已知問題-您可以在此處查看其討論。
引用James Roper ...
跨線程使用事務會導致死鎖。 這是問題所在:
所以我們陷入了僵局。 上面的場景描述了一個只有一個連接和一個線程的簡單場景,但是在更現實的場景中,我們有很多用戶看到生產死鎖,在這種現實場景中,連接池上有許多線程被阻塞,許多連接保持線程被阻塞以等待連接池阻止線程產生。
解決方案是使用異步連接池,不幸的是,JPA不支持該池。 解決方法是有一個專用線程池,該線程池用於異步獲取連接,這樣,當連接池用盡時,專用線程將阻塞,但這不會影響任何事情(可能是嵌套的嘗試獲得連接)因為它僅用於從池中獲取連接。
因此,您有3個選擇:
您可以使用此庫來正確處理實體管理器的關閉,但仍會遇到上述死鎖問題。
使用JPA.withTransaction
而不是JPA.withTransactionAsync
。
使用沒有這些問題的Ebean。
編輯:為了完整起見,我將添加選項4(我的首選解決方案),該選項不使用ORM框架,而是將其替換為jOOQ。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.