我在选择“get”查询循环期间遇到此异常。 你能告诉我怎么避免这个吗?
2014-01-21 18:54:36 [WARN]SqlExceptionHelper:143 SQL Error: 0, SQLState: 08S01
2014-01-21 18:54:36 [ERROR]SqlExceptionHelper:144 Communications link failure due to underlying exception:
** BEGIN NESTED EXCEPTION **
java.net.SocketException
MESSAGE: No buffer space available (maximum connections reached?): connect
STACKTRACE:
java.net.SocketException: No buffer space available (maximum connections reached?): connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:256)
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:271)
at com.mysql.jdbc.Connection.createNewIO(Connection.java:2771)
at com.mysql.jdbc.Connection.<init>(Connection.java:1555)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:173)
at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriver(DriverManagerDataSource.java:164)
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnectionFromDriver(AbstractDriverBasedDataSource.java:149)
at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnection(AbstractDriverBasedDataSource.java:119)
at org.hibernate.service.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:141)
at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:279)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:297)
at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:169)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:67)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:160)
at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1309)
at org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:399)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:335)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:105)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622)
at com.cinebot.db.Dao$$EnhancerByCGLIB$$7e1b7d44.getIngresso(<generated>)
at com.cinebot.service.LogAnalyzerService.processLogFile(LogAnalyzerService.java:273)
at com.cinebot.service.LogAnalyzerService.check(LogAnalyzerService.java:119)
at com.cinebot.service.LogAnalyzerThreadService$AnalisiLog.run(LogAnalyzerThreadService.java:55)
at com.cinebot.thread.StatusThreadStep.doStep(StatusThreadStep.java:91)
at com.cinebot.thread.ThreadAbstractService.process(ThreadAbstractService.java:57)
at com.cinebot.service.LogAnalyzerThreadService.run(LogAnalyzerThreadService.java:37)
at java.lang.Thread.run(Unknown Source)
** END NESTED EXCEPTION **
Last packet sent to the server was 0 ms ago.
我发现在此异常期间只有一个连接。 这是道:
@Autowired
private SessionFactory sessionFactory;
public Session getSession(){
return sessionFactory.getCurrentSession();
}
public <T> T get(Class<T> classe, Serializable id) throws Exception {
if(id==null) return null;
T obj = (T) getSession().get(classe, id);
return obj;
}
这是应用配置:
<bean id="dataSource" class="com.cin.web.DataSourceSelector" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>com.cin.db.entity</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.bytecode.use_reflection_optimizer">false</prop>
<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.search.autoregister_listeners">false</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop>
<prop key="hibernate.flushMode">always</prop>
</props>
</property>
<property name="mappingResources">
...
这是数据库选择器:
public class DataSourceSelector extends DriverManagerDataSource {
private String catalog;
private static Logger logss = Logger.getLogger(DataSourceSelector.class);
public String getCatalog(){
return catalog;
}
public DataSourceSelector(){
super();
String adb=DbConnector.getActiveDb();
if(!StringUtils.isBlank(adb)){
setDriverClassName("com.mysql.jdbc.Driver");
catalog=adb;
setUrl("jdbc:mysql://localhost/"+catalog);
logss.info("Selezionato DB: "+catalog);
setUsername("cin_java");
setPassword("password");
}
}
}
查询循环非常简单,有类似名称&gt; 20000次
dao.get(Entitiy.call,id)
我尝试添加session.flush()session.clear(),但在16000查询后仍然出现错误。
答案 0 :(得分:1)
通过您更新的帖子我分析了可能是休眠而不是在返回结果后释放数据库连接。因为哪个DB服务器进入了巨大的负载。
我会建议:
- 在session.flush();
session.clear()
和session.get(Entity.class, id);
- 如你设置的那样,你在循环检查中正在进行session.get(Entity.class, id);
,你不是每次都在创建SessionFactory。实现一个提供静态SessionFactory的类。
- 尝试使用c3p0
或任何其他想法来实现连接池。
更新(与提供静态SessionFactory的类相关)
使用hibernate与DB进行任何事务/操作时,您需要session
这个session
负责DB状态,操作(CRUD)。您将从SessionFactory
获取会话,该会话是通过阅读h hibernate.cfg.xml
等hibernate配置创建的。
要构建sessionFactory,我们使用SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
如果您在循环中调用此代码,那么这会给您带来更多麻烦。
我的想法是创建一个具有static SessionFactory
的类,该类将在使用DI
加载春季上下文时创建。
plz到My answer to this post我用 HibernateHelper_DI.xml 发布了 HibernateHelper.java 的代码,这将在上下文加载时创建静态sessionFactory。 / p>
如果您需要来自sessionFactory的session
,您只需致电:
Session session = HibernateHelper.getSession();
//work with session
session.flush();
session.clear();
Hibernate 4中不推荐使用 buildSessionFactory();
,现在我们必须使用buildSessionFactory(ServiceRegistry serviceRegistry)
您可以在HibernateHelper
中找到新方法。