0 0

HibernateDaoSupport 中getSession问题10

首先,如果数据源使用
<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource"
		destroy-method="close">
		<property name="driverClassName">
			<value>com.mysql.jdbc.Driver</value>
		</property>
		<property name="url">
			<value>jdbc:mysql://localhost:3306/test?characterEncoding=gbk</value>
		</property>
		<property name="username">
			<value>root</value>
		</property>
		<property name="password">
			<value>123456</value>
		</property>
	</bean>

,不用事务,在类中这样使用:

public class SpringSupportDao extends HibernateDaoSupport{
	
		
	public void saveOrUpdate(Person person){
this.getSession().saveOrUpdate(person);
}
}




然后另外一个类中循环1000次调用此saveorupdate方法,

在mysql中操作正常。
mysql的最大连接数是100个,
而如果数据库换成了oracle,最大连接数也是100个,会报以下错误,

严重: An attempt by a client to checkout a Connection has timed out.
Exception in thread "main" org.hibernate.exception.GenericJDBCException: Cannot open connection。

请教,这是mysql 和 oracle的不同吗?还是程序处理的其他原因?
问题补充
想问的是,不用事务的情况下,跟踪 那个getSession 每次都是打开一个新的session, 这个session在什么时候关闭呢?谁来控制呢?

另外,怎么得到当前session的连接数?

用下面这种方法取,每次都是0啊,是不是不对
this.getSessionFactory().getStatistics().getSessionOpenCount()
问题补充
是需要手动关闭的,但是我想知道的是,为什么mysql 100个链接就没事呢?

怎么监控session链接数呢?
问题补充
youjianbo_han_87 写道
你确定你的MySQL干活了吗? 个人感觉,超过它的连接数,它就自动拦截到后面的数据库操作请求了。而oracle会预先检查,并报错给你。。。建议你在MySQL的那个循环里面一直新增记录检验。。。


确定啊,数据都插入进去了

问题补充:如果你开启hibernate.generate_statistics, 那么当你通过 SessionFactory.getStatistics()调整正在运行的系统时,Hibernate将导出大量有用的数据. Hibernate甚至能被配置成通过JMX导出这些统计信息. 参考org.hibernate.stats中接口的Javadoc,以获得更多信息 <br /> <br />我设置了这个属性,通过this.getSessionFactory().getStatistics().getSessionOpenCount() 此方法得到当前打开的session。 <br />如果连续插入10000条数据,session数量能达到10000个。 <br /> <br />我用this.releaseSession(session); 这个关闭session了,可是session数量还是那么多。
2011年3月28日 21:40

22个答案 按时间排序 按投票排序

0 0

个人感觉不太可能是MySQL能开那么多连接,可能是你循环里面每次占用连接时间比较短,你循环10000次,其实还是那几十个连接。你在循环里面做一些占用连接时间较长的操作,比如多表连接查询结果打印到控制台,看看MySQL会不会挂。至于oracle为什么之前就报错,估计oracle有智能预判功能了。它判断你的连接不够做这些事。

2011年3月29日 09:25
0 0

MySQL 超过100个连接而不出现错误  应该是用了连接池。。
Oracle 报错估计是因为连接池没设置好。。。。
貌似JDBC2的连结池只是一个接口,没有真正的实现。oracle建议用第三方实现连结池。。

2011年3月28日 21:40
0 0

在程序端没有主动关闭session 早晚会出事的。你在mysql里面没问题,是因为mysql 的jdbc驱动跟oracle 不一样, 你可以去分析一下他的驱动源代码,初步估计是由于timeout时间比较短,而oracle的驱动timeout时间可能比较长。关闭不及时造成连接不上。
在使用spring的环境下去访问hibernate的api 是不推荐使用的一种做法,hibernate之所以 给出这个HibernateDaoSupport是提供一种访问spring模板的简便方法,而在其中重载了这个getSession 方法,结果造成了大家对这个getSession的滥用。一旦事务挂钩失败就会造成很严重的数据库连接问题,你这个程序单线程下肯定没问题,你要是挂在多线程环境下的mysql照样也会出问题的。

2011年3月28日 21:40
0 0

你可以这样,操作完了后,程序不要退出,去mysql / oracle 数据库里面去查看下,当前数据库的连接状况,是不是真的能查到100个连接,
另外:我没记错的话,mysql数据库的连接好像是默认8小时超时,oracle数据库是永不超时

2011年3月28日 21:40
0 0

和楼主一样,我好像也遇到了这样的情况,不过我是直接使用Hibernate的SessionFactory的getCurrentSession()方法来获取Session然后进行操作,但是在我的程序中发现,但执行登录操作的时候,Oracle的连接数暴增,按理说getCurrentSession()获取Session后,不需要手动关闭Session,当事务提交或回滚后会自动关闭Session,为什么我的程序会这样,我现在还没弄清楚

2011年3月28日 21:40
0 0

可能你的MYSQL用的引擎(看看是不是MYISAM)不支持事务,每次session操作事务都自动提交了,然后session关闭。而oracle支持事务,做了事务控制,等待所有的seesion都未出现问题,才提交事务,关闭所有的session.

2011年3月28日 21:40
0 0

我曾经做过实验,在配置事务之后,hibernateDaoSupport.getSessionFactory().getCurrentSession()所拿到的session和hibernateDaoSupport.getSession()所拿到的是同一个session。
但如果没有配置事务,调用hibernateDaoSupport.getSessionFactory().getCurrentSession()时会出现异常,好像意思是说运行的上下文没有事务。

hibernateDaoSupport.getSession()在api文档的意思是说从事务上下文获取session,如果没有则创建。

按我理解,如果不配置事务,则不存在事务的上下文,则每次都会创建新的session,一个session其实就包含一个数据库连接,自然就会出现这样的情况啦。
以上为个人理解,未必正确

2011年3月28日 21:40
0 0

个人觉得是jdbc驱动处理的问题,mysql估计是把在使用的connection重复使用了,而oracle则是实实在在的重新生成了。

2011年3月28日 21:40
0 0

你确定你的MySQL干活了吗? 个人感觉,超过它的连接数,它就自动拦截到后面的数据库操作请求了。而oracle会预先检查,并报错给你。。。建议你在MySQL的那个循环里面一直新增记录检验。。。

2011年3月28日 21:40
0 0

不让Spring管理事务,session一定要自己关掉,否则数据库连接会耗尽,mysql之所以没问题,是不是最大连接数配置大于1000?

# The maximum amount of concurrent sessions the MySQL server will
# allow. One of these connections will be reserved for a user with
# SUPER privileges to allow the administrator to login even if the
# connection limit has been reached.
max_connections=339

但无论配置多少,不用spring事务管理,务必手动关闭session

2011年3月28日 21:40
0 0

kidd3166 写道
你这样拿Session要主动释放的
releaseSession(Session) 这个方法可以使用

这样真的可以吗?我还真没试过,以前也遇到过无事务包裹会出现session的问题,而且当又用到异步(ajax)时就更复杂了,最后的解决方案就是用事务。而且使用事务时又要注意,不能try掉dao调用而不抛异常(error,runtime),否则spring就捕获不到,出错了没法回滚,这种潜在的问题还是蛮可怕的!

2011年3月28日 21:40
0 0

这个错是不是因为mysql和oracle的链接的时间不一样?

2011年3月28日 21:40
0 0

表示LZ头像都很..Hibernate连接多个数据库靠谱么?

2011年3月28日 21:40
0 0

你这样拿Session要主动释放的
releaseSession(Session) 这个方法可以使用

2011年3月28日 21:40
0 0

集成Spring了,你应该用HibernateTemplate

2011年3月28日 21:40
0 0

HibernateDaoSupport的getSession()得到的Session会参与Spring管理的事务中,但是不能自动的关闭

但是为什么 mysql  不会出现连接数已满,无session可用的问题 ??

在使用 mysql的情况下,这些 连接会被自动释放么?

2011年3月28日 21:40
0 0

ssg108 写道
想问的是,不用事务的情况下,跟踪 那个getSession 每次都是打开一个新的session, 这个session在什么时候关闭呢?谁来控制呢?

另外,怎么得到当前session的连接数?

用下面这种方法取,每次都是0啊,是不是不对
this.getSessionFactory().getStatistics().getSessionOpenCount()


getSession() 你一直在 dao 层里是不会释放的,包裹了事物的话,在事物代码里会释放

2011年3月28日 21:40
0 0

请参考此文:http://blog.csdn.net/bluishglc/archive/2011/03/19/6261905.aspx

2011年3月28日 21:40
0 0

lz的头像让我想起了她...心酸了...

2011年3月28日 21:40
0 0

不用批量吗

2011年3月28日 21:40
0 0

姐  你为什么要这么做了  为了什么 测试数据库连接??还是什么

2011年3月28日 21:40
0 0

An attempt by a client to checkout a Connection has timed out.”是比如其他原因引起的数据库连接不释放,导致超过最大连接数,引起后边的client请求无限等待了吧.

2011年3月28日 21:40

相关推荐

Global site tag (gtag.js) - Google Analytics