首先,我给出了一些数据点。
接下来将描述问题。
数据点:
[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 文档说(link):
The most common pattern in a multi-user client/server application is session-per-request.
[D2] 还建议使用连接池库
C3P0
来池化与数据库的连接。如 postgres 文档( link )所述:Pg will usually complete the same 10,000 transactions faster by doing them 5, 10 or 20 at a time than by doing them 500 at a time.
[D3] 还有
JDBC
给定一个连接,我们可以一次运行一个事务,并在该事务中运行尽可能多的语句。由应用程序(C3P0)确保执行两个不同事务方法的两个不同线程不应该使用相同的连接,并且一个应该在调用另一个方法之前等待。
问题:
现在,如果我们使用带有注解的托管 bean 事务模式以及带有 hibernate 和每个请求 session 的连接池(假设只有 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(...)
将进行只读查询,两个线程都可以使用相同的连接并且不阻止线程执行查询。在上述情况下,我们保持该连接空闲并保持线程等待。
主要问题
有没有一种方法可以让 hibernate 说特定的 hibernate 事务是只读的,然后 hibernate 可以重用已经获得的连接,而不是从连接池中请求新的连接?
找到/建议的解决方案很少:(不令人信服)
1如果您非常担心,请不要使用注释使用事务,自己使用 hibernate session .....不,我喜欢那种模式:)
2 Hibernate 提供
ConnectionRelease
link可设置为 after_statement
的选项.第一个 Hibernate C3P0 连接池提供程序不支持 after_statement。
其次,仅释放并重新获取连接将是开销。
最佳答案
您不能将来自不同线程的事务多路复用到一个 JDBC 连接。即使 JTA 规范说这可能是可能的,但实际上这不会发生,而且 JDBC 驱动程序是同步的。
1) 和 2) 都没有,也没有适合您需求的正确建议。
after_statement
incurs some penalty ,而它仍然将事务绑定(bind)到连接。 因此,可行的替代方案是:
关于java - 是否可以在单个 JDBC 连接上多路复用多个只读事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36920695/