java.sql.SQLException: Couldn't get connection because we are at maximum connection count (50/50) an

时间:2023-01-19 21:36:18
昨天一同事碰到一个问题:当在一个画面连续点击多次之后(每次点击都会执行数据连接的操作),就会报出一个“java.sql.SQLException: Couldn't get connection because we are at maximum connection count (50/50) and there are none available”的异常。从字面上看就是数据库的连接数不够,超出了最大连接数。后来网上查了下,才明白原来是在Hibernate中的配置有问题:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.Oracle9Dialect
</prop>
<prop key="hibernate.show_sql">true</prop>
<!--<prop key="hibernate.connection.autocommit">false</prop>-->
<prop key="hibernate.proxool.pool_alias">dbpool</prop>
<prop key="hibernate.proxool.xml">ProxoolConf.xml</prop>
<prop key="hibernate.connection.release_mode">auto</prop>
<prop key="hibernate.connection.provider_class">org.hibernate.connection.ProxoolConnectionProvider</prop>
</props>
</property>
<property name="mappingDirectoryLocations">
<value>classpath:</value>
</property>
<property name="lobHandler" ref="lobHandler"></property>
</bean>

这里的 auto配置,与数据库连接池的配置:
<prototype-count>5</prototype-count>
<maximum-connection-count>50</maximum-connection-count>
<maximum-active-time>180000</maximum-active-time>
<maximum-connection-lifetime>7200000</maximum-connection-lifetime>

合在一起使用时,就会出问题:当我点击页面太快,而上一次,点击页面产生的连接还没有被释放(从配置上看,产生一个新的连接后,需要720s才会释放,个人觉得本身这720s才释放一个连接,这已经是一个很长生命周期的连接,是件很浪费资源事),所以点击太快就会产生一个新的连,很快50个连接用完之后,就会出现抛出上述异常。

解决办法:
1、更改 prop key="hibernate.connection.release_mode配置的模式为:after_transaction
Hibernate 的连接释放模式:hibernate.connection.release_mode 有三个选择:after_statement/after_transaction/on_close, 默认的是on_close所以,这里要改成 after_transaction
2、如果在进行数据库访操作时,可以操作到session对象,确保session对象在完成数据库操作后,调用close()方法。
3、在打开session后,手动开启一个transaction:session.beginTransaction(),当完成数据库操作时,再手动提交事务: t ransaction .commit();