Выборка объекта снова в тупик при использовании JPA с потоками - PullRequest
0 голосов
/ 31 октября 2018

Я использую JPA 2.2 с Hibernate 5.3.7 для извлечения большого количества данных из базы данных.

Чтобы максимально уменьшить использование оперативной памяти в системе, я обрабатываю результаты запроса с использованием потоков.

Ниже приведен упрощенный код, который я использую:

String myQuery = "SELECT entity FROM MyEntity entity";
EntityManagerFactory emFactory = Persistence.createEntityManagerFactory(connector,propReader.getPropertiesObject());
EntityManager entityManager = emFactory.createEntityManager();
Session session = entityManager.unwrap(Session.class);
Stream<MyEntity> stream = session.createQuery(myQuery, MyEntity.class).stream();
stream.forEach(entity -> proccessEntity(entity));

В большинстве случаев это работает очень хорошо, но проблема в том, что иногда возникают взаимоблокировки, когда stream пытается получить следующую сущность. Ниже приведен пример такого случая:

org.hibernate.exception.LockAcquisitionException: could not advance using next()
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:123)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
    at org.hibernate.internal.ScrollableResultsImpl.convert(ScrollableResultsImpl.java:69)
    at org.hibernate.internal.ScrollableResultsImpl.next(ScrollableResultsImpl.java:104)
    at org.hibernate.query.internal.ScrollableResultsIterator.hasNext(ScrollableResultsIterator.java:33)
    at java.util.Iterator.forEachRemaining(Iterator.java:115)
    at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
    at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
    at testing.deadlock.Main.main(Main.java:115)
 Caused by: java.sql.SQLException: Transaction (Process ID 59) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
    at net.sourceforge.jtds.jdbc.SQLDiagnostic.addDiagnostic(SQLDiagnostic.java:372)
    at net.sourceforge.jtds.jdbc.TdsCore.tdsErrorToken(TdsCore.java:2988)
    at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2421)
    at net.sourceforge.jtds.jdbc.TdsCore.getNextRow(TdsCore.java:805)
    at net.sourceforge.jtds.jdbc.JtdsResultSet.next(JtdsResultSet.java:611)
    at com.mchange.v2.c3p0.impl.NewProxyResultSet.next(NewProxyResultSet.java:685)
    at org.hibernate.internal.ScrollableResultsImpl.next(ScrollableResultsImpl.java:99)
    ... 10 more

Могу ли я как-то заставить поток попытаться снова получить объект несколько раз, когда возникает такая тупик? Если нет, то какие другие решения прикладного уровня вы предлагаете?

Спасибо!

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