首先,我没有给出多少数据。
接下来将是所描述的问题。
数据点:
D1 In Hibernate,Annotation和managed objects world,我看到了一个常见的模式
@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还建议使用连接池库C3P0来连接数据库,如postgres文档(链接)中所述:
Pg通常一次完成相同的10,000件事务比一次做500件事情快5、10或20件。
D3也和JDBC一起
给定一个连接,我们可以一次运行一个事务,在该事务中可以运行任意数量的语句。
更新了应用程序(C3P0),以确保执行两个不同事务方法的两个不同线程不应该使用相同的连接,其中一个应该在调用另一个方法之前等待。
问题:
现在,如果我们使用托管bean事务模式,使用注释以及一个连接池(假设只有一个连接),则使用hibernate和每个请求的会话。
另外,让我们说代码类似于
@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完成执行,执行大约需要15万秒。
理想情况下,考虑到getStuff(...)只进行只读查询,两个线程都可以使用相同的连接,并且不阻止线程执行查询。
在上述情况下,我们将保持该连接处于空闲状态,并使线程等待。
主要问题
,我是否可以告诉hibernate,一个特定的hibernate事务是只读的,然后hibernate可以重用一个已经获得的连接,而不是从连接池?请求一个新的连接。
很少找到/建议的解决方案:(不令人信服)
1如果你这么担心的话,不要使用使用注释的事务,自己使用hibernate会话……不,我喜欢那种模式:)
2 Hibernate提供了一个ConnectionRelease链接选项,可以设置为after_statement。
首先,Hibernate C3P0连接池提供程序不支持after_statement。
其次,这将是一个开销,只需释放并重新获取一个连接。
发布于 2016-04-29 06:05:10
不能从不同线程到一个JDBC连接进行多路事务处理。即使JTA规范说这是可能的,但实际上,这是不可能的,而且JDBC驱动程序是同步的。
并对你的需求提出正确的建议。
after_statement 招致一些惩罚,而它仍然将事务绑定到连接。因此,可行的替代办法是:
https://stackoverflow.com/questions/36920695
复制相似问题