Обновление БД - длительная операция не удалась - PullRequest
0 голосов
/ 23 ноября 2011

Я использую hibernate для помещения объекта в БД. БД - версия сообщества MYSQL. Все обновление выполняется в транзакции.

Код, который делает это так:

getHibernateTemplate () saveOrUpdate (заказ);.

Нет проблем, когда заказ небольшой, но когда я тестировал сценарий с почти 1 000 000 предметов, я столкнулся с этой проблемой:

11-22@12:56:48 DEBUG PersistOrderServiceImpl [flow.ottoImportOrderPlacementInboundFlow.1] - saving order instance::
[Order [orderId=080661, vatOrderNumber=SODE000001, orderDate=Tue Nov 08 10:12:37 CET 2011, shippingMethod=STANDARD, ....

11-22@13:02:12 ERROR JDBCTransaction [flow.ottoImportOrderPlacementInboundFlow.1] - JDBC rollback failed
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
.....
....
11-22@13:02:12 ERROR TransactionInterceptor [flow.ottoImportOrderPlacementInboundFlow.1] - Application exception overridden by rollback exception
java.lang.NullPointerException
        at com.mysql.jdbc.Field.setConnection(Field.java:972)
        at com.mysql.jdbc.StatementImpl.getGeneratedKeysInternal(StatementImpl.java:1912)
        at com.mysql.jdbc.StatementImpl.getGeneratedKeysInternal(StatementImpl.java:1905)
        at com.mysql.jdbc.StatementImpl.getGeneratedKeys(StatementImpl.java:1885)
        at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.getGeneratedKeys(NewProxyPreparedStatement.java:1749)
        at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:97)
        at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:57)
......
...... 

Кажется, что проблема проявляется примерно через 5 минут и 24 секунды, или всего 324 секунды.

Я не могу найти в журнале MySQL ничего об этом.

Кажется, это не связано с памятью, потому что, когда я уменьшаю память, исключение отличается:

java.lang.OutOfMemoryError: GC overhead limit exceeded 

Я не знаю, является ли это какой-то ошибкой в ​​Hibernate MySQL или это какая-то настройка, ограничивающая время, в течение которого может выполняться обновление / соединение / транзакция.

Я не смог найти ничего связанного с документацией MySQL или в настройках Hibernate.

Буду признателен за любую помощь в отладке или решении этой проблемы.

РАЗРЕШЕНО: Проблема была в файле c3p0.properties, который был в моей библиотеке Tomcat. Он содержит: c3p0.unreturnedConnectionTimeout = 300, то есть больше или меньше времени, после которого я получаю ошибку. После того, как я удалил его, обновление прошло, без проблем.

1 Ответ

2 голосов
/ 23 ноября 2011

Пул соединений с базой данных настроен со значением времени ожидания. Как только транзакция началась (заимствовала соединение из пула) и не закончилась (не освобождает соединение с пулом) до этого значения тайм-аута, соединение закрывается пулом соединения с базой данных (помеченным как прекращенное). Когда hibernate пытается зафиксировать транзакцию (обратите внимание, что hibernate не может узнать, закрыто ли здесь соединение), драйвер видит исключение. Попробуйте разбить вашу транзакцию на более мелкие транзакции (зафиксируйте элементы партиями). После того, как все заказы будут вставлены в БД, вставьте свой объект Order. Однако код вашего приложения должен позаботиться о сбое пакетной фиксации и последующей логике отката.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...