Задержки пакетных заданий JSR-352 между фрагментами: как сократить время фиксации без массового удаления?JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Задержки пакетных заданий JSR-352 между фрагментами: как сократить время фиксации без массового удаления?

Сообщение Anonymous »

Я запускаю пакетное задание JSR-352 (точнее, реализацию Apache JBatch) в среде JEE (WebSphere с EclipseLink в качестве поставщика JPA).
Пакетная обработка записей базы данных порциями и удаляет объекты на основе их идентификаторов с некоторыми условиями. Проблема в том, что после удаления фрагмента объектов следующий фрагмент считывается только через несколько минут, причем задержка увеличивается пропорционально размеру фрагмента, например:
  • Размер фрагмента = 50: задержка между фрагментами составляет ~10 минут.
  • Размер фрагмента = 10: задержка между фрагментами составляет ~2 минуты.
    Моя работа конфигурация:
    • Считыватель извлекает идентификаторы из базы данных на основе условия. Я ограничиваю результаты запроса с помощью query.setMaxResults(chunkSize), чтобы избежать одновременного получения всех идентификаторов.
    • Писатель удаляет объекты по их идентификаторам в цикле, используя em.remove< /code>, обеспечивая правильную обработку каскадных удалений для каждого объекта.
    Задание работает, но значительно замедляется по мере увеличения размера фрагмента. Моя установка включает в себя:
    • Пул соединений, настроенный в WebSphere.
      Транзакции, управляемые JPA (JTA).
    Я также пробовал массовое удаление, например DELETE FROM Entity WHERE id IN (...), но это не вариант для меня, потому что они не выполняют каскадное удаление связанным организациям. Объект, который я хочу удалить, очень сложный, и в журналах я вижу, что удаление этого объекта приводит к удалению строк примерно из 50 таблиц (хороший ли это дизайн - другой вопрос)
    Использование em.flush() в моем средстве записи после обработки каждого фрагмента приводит к тайм-ауту транзакции, поэтому я не использую флеш.
    Я также заметил, что em .clear() после каждого фрагмента без flash решает проблему зависания, но изменения не сохраняются в базе данных. Так что просто делать ясность тоже неправильно. Возможно, EntityManager содержит слишком много управляемых объектов, или блокировки/ограничения базы данных могут вызывать замедление работы, но я много пробовал, но не знаю, как решить эту проблему.
    Вот код моего Reader:
    import java.io.Serializable;

    import javax.batch.api.chunk.AbstractItemReader;
    import javax.batch.runtime.context.StepContext;
    import javax.inject.Inject;
    import javax.inject.Named;
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;

    import org.apache.batchee.cdi.scope.StepScoped;

    @StepScoped
    @Named
    public class MyReader implements AbstractItemReader {

    private int chunkSize = 50;

    @PersistenceContext
    private EntityManager em;

    private List currentIdsInChunk;
    private int currentBatchPosition = 0;

    ...constructor

    ...reading the chunksize from batch properties

    @Override
    public Long readItem() throws Exception {

    if (currentIdsInChunk == null || currentBatchPosition >= currentIdsInChunk.size()) {
    LOGGER.info("Loading Ids for the next chunk...");
    currentIdsInChunk = em.createNativeQuery("SELECT e.id FROM Entity e WHERE e.condition = :condition")
    .setParameter("condition", "SOME_CONDITION")
    .setMaxResults(chunkSize)
    .getResultList();
    if (currentIdsInChunk.isEmpty()) {
    return null;
    }
    currentBatchPosition = 0;
    }
    return currentIdsInChunk.get(currentBatchPosition++);
    }

    @Override
    public Serializable checkpointInfo() {
    return currentBatchPosition;
    }
    }

    Мой писатель выглядит так:
    import javax.enterprise.context.Dependent;
    import javax.inject.Inject;
    import javax.inject.Named;
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;

    import org.apache.batchee.extras.typed.NoStateTypedItemWriter;

    @Named
    @Dependent
    public class MyDeleteWriter implements NoStateTypedItemWriter {

    @PersistenceContext
    private EntityManager em;

    ... constructor

    @Override
    public void writeItems(List ids) throws Exception {
    int deletedCount = 0;
    for (Long id : ids) {
    Entity entity = em.find(Entity.class, id);
    if (entityToDelete != null) {
    if (!em.contains(entityToDelete)) {
    entityToDelete = em.merge(entityToDelete);
    }
    em.remove(entityToDelete);
    deletedCount++;

    } else {
    // log entity does not exist
    }
    }

    }
    }


    Подробнее здесь: https://stackoverflow.com/questions/792 ... thout-bulk
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»