[英]Is it possible to multiplex multiple read-only transactions on a single JDBC Connection
首先,我給出的數據很少。
接下來將描述問題。
數據點:
[D1]在Hibernate
和Annotation
和managed objects
世界中,我看到了一種常見的模式,例如
@Transactional
public void createStuff(..){
// get entity manager and call persist and other operatation
}
@Transactional
public SomeDtoObject getStuff(..){
// get entity manager and call find and getter to polulate a object to return
}
在托管bean中,當我們調用此方法時,將啟動並提交Hibernate事務。
Hibernate文檔說( 鏈接 ):
在多用戶客戶端/服務器應用程序中,最常見的模式是每次請求會話。
[D2]此外,建議使用postgres文檔( 鏈接 )上所述的連接池庫C3P0
來池化與數據庫的連接:
Pg通常一次完成5、10或20次會比一次完成500次更快地完成相同的10,000個事務。
[D3]同樣使用JDBC
給定一個連接,我們可以一次運行一個事務,並且可以在該事務中運行任意數量的語句。
取決於應用程序(C3P0),以確保執行兩個不同事務方法的兩個不同線程不應使用相同的連接,並且一個應在調用另一個方法之前等待。
問題:
現在,如果我們使用帶注釋的托管bean事務模式以及帶有休眠和每次請求會話數的連接池( 僅說1個連接 )
還可以說代碼就像
@Transactional
public SomeDtoObject getStuff(..){
// get entity manager and call find and getter to polulate a object to return
SomeEntity se = entityManager.find(someentity, primaryKey);
//create Dtos
// access someEntity to all over this method to create SomeDtoObject that we have to return.
// also may access some file on system to fetch some data is order to populate someDtoObject.
// overall let say the method take 150 milli second to do all its work
}
現在,假設有兩個不同的線程( T1
, T2
)調用getStuff(...) T1
將進入該方法並從連接池獲取jdbc連接。
當T2
到達entityManager.find
, C3P0
將檢查是否沒有連接,它將使T2
處於保持狀態,直到T1
完成執行,這大約需要150毫秒的時間。
理想情況下,假設getStuff(...)
將執行只讀查詢,則兩個線程可以使用相同的連接,並且不保留執行查詢的線程。
在上述情況下,我們保持該連接空閑,並保持線程等待。
主要問題
我是否可以說一種方式休眠,即特定的休眠事務是只讀的,然后休眠可以重用已經獲取的連接,而不是從連接池中請求新的連接?
很少找到/建議解決方案:(不令人信服)
1如果您非常擔心,請不要使用帶有注釋的事務,而要自己使用休眠會話.....不,我喜歡這種模式:)
2 Hibernate提供一個ConnectionRelease
鏈接選項,可以將其設置為after_statement
。
第一 Hibernate C3P0連接池提供程序不支持after_statement。
其次 ,釋放並重新獲取連接將產生開銷。
您不能將來自不同線程的事務多路復用到一個JDBC連接。 即使JTA規范說這是可能的,但實際上並沒有發生,並且JDBC驅動程序是同步的。
1)和2)都沒有,也沒有適合您需求的建議。
after_statement
產生一定的懲罰 ,盡管它仍將事務綁定到連接。 因此,可行的替代方案是:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.