Сбой линии связи при длительном спящем соединении mysql - PullRequest
0 голосов
/ 22 апреля 2020

У нас есть одно устаревшее приложение, в котором мы используем java приложение, которое подключается к Mysql БД. У нас есть один метод, который выполняет итерации по элементам в БД, который выполняется в течение 5–6 часов (я знаю, что транзакции продолжительностью от 5 до 6 часов неправильны, и мы должны принять альтернативную стратегию, такую ​​как пакетная обработка, но эту хотел бы решить на данный момент.) для завершения операции.

Этот метод, как показано ниже:

EntityManager entityManagerMAXXSOFT = JPAFactory.getEntityManagerFactoryMAXXSOFT().createEntityManager();
        List<de.tecmaxx.database.model.maxxsoft.Journal> journalList;
        int vorbestellungen = 0;
        try {
            entityManagerMAXXSOFT.getTransaction().begin();
            Query q = entityManagerMAXXSOFT.createQuery("SELECT a FROM de.tecmaxx.database.model.maxxsoft.Journal a WHERE a.status NOT LIKE :complete AND a.status NOT LIKE :cancelled");
            q.setParameter("complete", "complete");
            q.setParameter("cancelled", "cancelled");
            journalList = q.getResultList();
            entityManagerMAXXSOFT.getTransaction().commit();
            }
            finally {
                entityManagerMAXXSOFT.close();
            }
            for (Iterator iterator = journalList.iterator(); iterator.hasNext();) {
                Journal journal = (Journal) iterator.next();
                List<de.tecmaxx.database.model.maxxsoft.Journalpo> journalpoList = journal.getJournalpos();
                for (Iterator iterator2 = journalpoList.iterator(); iterator2.hasNext();) {
                    Journalpo journalpo = (Journalpo) iterator2.next();
                    if (journalpo.getCaoarticlenumber().equals(caoartikelnummer)) {
                        vorbestellungen = vorbestellungen+journalpo.getQuantity();
                    }
                    List<de.tecmaxx.database.model.maxxsoft.Journalposelement> journalposelementList = journalpo.getJournalposelements();
                    for (Iterator iterator3 = journalposelementList.iterator(); iterator3.hasNext();) {
                        Journalposelement journalposelement = (Journalposelement) iterator3.next();
                        if (journalposelement.getCaoarticlenumber().equals(caoartikelnummer)) {
                            vorbestellungen = vorbestellungen+journalposelement.getQuantity();
                        }
                    }
                }
            }

Мы подключаемся к БД, используя Hibernate и используя соединение c3p0 пул и конфигурация выглядят следующим образом:

<properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://188.74.48.70:3306/moebel_guenstig24_de_test?autoReconnect=true" />
            <property name="javax.persistence.jdbc.user" value="moebel-guenstig2" />
            <property name="javax.persistence.jdbc.password" value="SAuxBD8k9IT1Iq076bQM" />
            <!--<property name="javax.persistence.jdbc.url" value="jdbc:mysql://188.74.48.70:3306/moebel_guenstig24_de_m2" />
            <property name="javax.persistence.jdbc.user" value="mg24_test" />
            <property name="javax.persistence.jdbc.password" value="ZPT\Vrc." />-->

            <!-- Hibernate properties -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <property name="hibernate.show_sql" value="false" />
            <property name="hibernate.connection.pool_size" value="100"  />
            <property name="hibernate.enable_lazy_load_no_trans" value="true"/>
            <property name="hibernate.c3p0.acquire_retry_attempts" value="0"/>
            <!--<property name="hibernate.hbm2ddl.auto" value="create" />-->

            <!-- Configuring Connection Pool -->
            <property name="connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider" /> 
            <property name="hibernate.c3p0.min_size" value="1" />
            <property name="hibernate.c3p0.max_size" value="20" />
            <property name="hibernate.c3p0.timeout" value="25200" />
            <property name="hibernate.c3p0.max_statements" value="0" />
            <property name="hibernate.c3p0.idle_test_period" value="100" />
            <property name="hibernate.c3p0.preferredTestQuery" value="select 1;" />
            <property name="hibernate.c3p0.acquire_increment" value="3" />
        </properties>

Мы получаем случайную ошибку иногда через 5 минут или иногда через 2–3 часа:

Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

The last packet successfully received from the server was 19.206 milliseconds ago.  The last packet sent successfully to the server was 19.206 milliseconds ago.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:377)
    at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1036)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3427)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3327)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3814)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2435)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2582)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2530)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1907)
    at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2030)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:71)
    ... 29 more
Caused by: java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at com.mysql.jdbc.util.ReadAheadInputStream.fill(ReadAheadInputStream.java:100)
    at com.mysql.jdbc.util.ReadAheadInputStream.readFromUnderlyingStreamIfNecessary(ReadAheadInputStream.java:143)
    at com.mysql.jdbc.util.ReadAheadInputStream.read(ReadAheadInputStream.java:173)
    at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2911)
    at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3337)
    ... 37 more

Я полагаю, у нас ненадежная сеть, которая причиной этого может быть. Как мы можем надежно восстановить соединение ? или это как-то связано с размером пула соединений ?

...