[英]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.