1

数秒ごとに大量のレコードを挿入する次のメソッドがあります。しばらく実行すると、次のようなエラーが発生します。

エラー: 通信リンク障害

サーバーから正常に受信された最後のパケットは 523 ミリ秒前です。サーバーに正常に送信された最後のパケットは 8 ミリ秒前です。

2013 年 5 月 16 日 9:48:30 AM com.mchange.v2.c3p0.stmt.GooGooStatementCache checkinStatement 情報: チェックインされたステートメントに問題があり、破棄しています。

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: ステートメントが閉じられた後、操作は許可されません。


接続を開閉するために使用するコードは次のとおりです。

public DataControllerImp() {
    session = HibernateUtil.getSessionFactory().openSession();
}

@Override
public void saveMessage(ArrayList<Message> messages) {
    Transaction tx = session.beginTransaction();

    for (int i = 0; i < mesages.size(); i++) {
        Message message = messages.get(i);

        try {
            session.save(message);
            if (i % 75 == 0) { 
                // flush a batch of inserts and release memory:
                session.flush();
                session.clear();
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

    tx.commit();
}


c3p0 接続プーリングも使用しています。私の構成は次のようになります。

<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>        
<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="hibernate.c3p0.idle_test_period">300</property>
<property name="hibernate.c3p0.min_size">3</property>
<property name="hibernate.c3p0.max_size">20</property>
<property name="hibernate.c3p0.max_statements">50</property>
<property name="hibernate.c3p0.timeout">300</property>
<property name="hibernate.c3p0.acquireRetryAttempts">1</property>
<property name="hibernate.c3p0.acquireRetryDelay">250</property>


接続の開閉が間違っていますか? このエラーが発生してプログラムが停止するのを防ぐために何を変更できるか教えてください。

4

2 に答える 2

2
    Transaction tx = session.beginTransaction();
    try {
        for (int i = 0; i < mesages.size(); i++) {
            Message message = messages.get(i);
            session.save(message);
            if (i % 75 == 0) { 
                // flush a batch of inserts and release memory:
                session.flush();
                session.clear();
            }
        }
        tx.commit();
    }catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        tx.rollBack();
    }finally{
        session.close();
    }
}
于 2013-05-16T17:58:06.323 に答える
0

むしろ、任意のオブジェクト タイプのジェネリック メソッドを作成し、オブジェクトを渡します。リストのロジックも追加します。

public void save(Object obj) {
    Session session = null;
    Transaction transaction = null;
    try {
        session = sessionFactory.getCurrentSession();
        transaction = session.beginTransaction();
        session.save(obj);
        session.flush();
        transaction.commit();
    } catch (JDBCException jde) {
        logger.fatal("Error occured in database communication", jde);
        transaction.rollback();
        throw new RuntimeException(jde);
    } finally {
        if (session.isOpen()) {
            session.close();
        }
    }
}
于 2015-02-06T15:03:43.907 に答える