java - Hibernate-Mysql 读取循环异常

标签 java mysql hibernate

我在选择“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");
        }
    }

}

查询循环非常简单,有类似>20000次的东西

dao.get(Entitiy.call,id)

我尝试添加 session.flush() session.clear() 但在 16000 次查询后我仍然收到该错误。

最佳答案

根据您更新的帖子,我分析可能是 hibernate 在返回结果后未释放数据库连接。因此数据库服务器负载巨大。

我建议:

-在 session.get(Entity.class, id); 之后使用 session.flush();session.clear()

-当您设置时,您正在执行 session.get(Entity.class, id); 循环检查,您不会每次都创建 SessionFactory。实现一个提供静态 SessionFactory 的类。

-尝试使用 c3p0 实现连接池或任何其他想法。

更新(与提供静态SessionFactory的类相关)

当您使用 hibernate 对数据库进行任何事务/操作时,您将需要一个 session ,此 session 负责数据库状态、操作(CRUD)。您将从 SessionFactory 获取 session ,该 session 是通过读取 hibernate 配置(如 hibernate.cfg.xml)创建的。

为了构建 sessionFactory,我们使用 SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); 如果您在循环中调用此代码,那么这会给您带来更多麻烦。

我的想法是创建一个具有static SessionFactory的类,它将在使用DI加载Spring上下文时创建。

请联系My answer to this post我在其中发布了 HibernateHelper.javaHibernateHelper_DI.xml 的代码,它将在上下文加载时创建静态 sessionFactory。

当您需要来自 sessionFactory 的 session 时,您只需调用:

Session session = HibernateHelper.getSession();
//work with session
session.flush();
session.clear();

buildSessionFactory(); 在 Hibernate 4 中已弃用,现在我们必须使用 buildSessionFactory(ServiceRegistry serviceRegistry) 你可以在 HibernateHelper 中找到新方法.

关于java - Hibernate-Mysql 读取循环异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21265738/

相关文章:

java - Spring mvc 多实体数据库持久化

Java 泛型查询(上限通配符)

php - 使用事件名称而不是 ID 删除记录

java - 在 Java 中存储多个列表的最佳方式是什么?

java - JPA Hibernate 搜索预测

java - 如何在 java 中将 java.sql.blob 转换为 base64 编码的字符串

java - 针对不同版本的 Java 代码或预处理进行细微更改?

java - void 变量有什么用?

java - 重新抛出异常 : Why does the method compile without a throws clause?

php - 使用 PHP 在一个 MySQL 查询中获取多行的最佳方法是什么?