Дело: файл с более чем 1 млн записей.Прочитайте файл и сохраните записи в базе данных Oracle.
Решение: используйте интерфейс Hibernate statelessSession, поскольку в этом конкретном случае нет необходимости использовать контекст постоянства.Загружать записи из файла в цикле while 100k каждый раз и фиксировать их немедленно.
Реализация: вверху у меня есть метод loadAllDictionaries () с аннотацией @Transactionalс таймаутом 7200. Он запускает цепочку методов и попадает в цикл while:
while(!(recordList = loadIDictionariesPackage(reader)).isEmpty()){
processRecords(recordList, dictionaryVersion, dictionaryType, filename);
}
Теперь processRecords (...) делает некоторыевещи и в какой-то момент вызывает следующее (обратите внимание на распространение)
@Transactional(propagation = Propagation.REQUIRES_NEW, timeout = 900) //timeout is unnecessary since it takes around 2,5 minutes.
public void saveInStatelessSession(List<T> entities) throws HibernateException {
StatelessSession session = this.getSessionFactory().openStatelessSession();
session.beginTransaction();
entities.forEach(entity -> session.insert(getEntityName(), entity));
session.getTransaction().commit();
session.close();
}
Итак, после завершения цикла while и сохранения в БД более 1 млн. записей поток возвращается к loadAllDictionaries() и вводит другой метод @Transactional addNewLog (...)
@Transactional
public void addNewLog(AbstractLogEntry message) {
final EventLogDefinition definition = logEntryDAO.getDefinitionForEntry(message);
doAddNewLog(message, definition, null);
}
Здесь getDefinitionForEntry() выдает исключение
com.atomikos.datasource.ResourceException: XA resource 'dataSource': resume for XID '3139322E3136382E35362E312E746D313534323739343839373335343033363332:3139322E3136382E35362E312E746D33373939' raised -4: the supplied XID is invalid for this XA resource
Что странно.Это происходит, только если ~ 200k или более записей сохранены.Не имеет значения, если я изменю пакет с 100 КБ до 10 КБ, что увеличивает количество транзакций.Я думал, что это может быть тайм-аут Atomicos, но в моем файле контекста приложения он установлен на 3000
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.J2eeUserTransaction" depends-on="userTransactionService">
<property name="transactionTimeout" value="3000" />
</bean>
Если я удаляю строку
@Transactional(propagation = Propagation.REQUIRES_NEW, timeout = 900)
из saveInStatelessSession метод, чем когда loadAllDictionaries () транзакция пытается зафиксировать данные, которые я получаю
ERROR org.springframework.transaction.UnexpectedRollbackException: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is javax.transaction.RollbackException: Prepare: NO vote
Есть ли у вас какие-либо мысли о том, что может бытьпроблема здесь?