Spring Batch - есть ли способ зафиксировать данные, даже если порция вызвала какое-то исключение? - PullRequest
0 голосов
/ 03 мая 2020

У меня есть процесс, который читает из очереди, обрабатывает и записывает в БД. Даже если процесс не удается, я должен хранить в БД. Но шаги Spring Batch являются транзакционными и всегда отменяют изменения. Итак, есть ли способ зафиксировать данные, даже если порция вызвала какое-то исключение?

РЕДАКТИРОВАТЬ I:

Я пытался с помощью Tasklet, но получил то же поведение.

Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 03 мая 2020

Во время настройки шага вы можете использовать noRollback() для настройки списка исключений, которые не вызовут откат. Любые исключения, которые являются подклассом настроенного исключения, не будут откатываться. Это означает, что если вы просто хотите никогда не выполнять откат, установите его как Exception, который является родителем всех исключений.

Пример можно найти в документах :

@Bean
public Step step1() {
    return this.stepBuilderFactory.get("step1")
                .<String, String>chunk(2)
                .reader(itemReader())
                .writer(itemWriter())
                .faultTolerant()
                .noRollback(Exception.class)
                .build();
}
0 голосов
/ 03 мая 2020

Я пытался использовать noRollback(), как предложил Кен Чан, но не сработало. Также попробуйте добавить указанные c исключения, но он продолжает выполнять откат.

Условный поток на уровне шага отсутствует на уровне элемента, поэтому он мне не помогает. Также пытался с Слушателями, но документация гласила:

This listener is designed to work around the lifecycle of an item. This means that each method should be called once within the lifecycle of an item and in fault tolerant scenarios, any transactional work that is done in one of these methods would be rolled back and not re-applied. Because of this, it is recommended to not perform any logic using this listener that participates in a transaction.

Я решил свою проблему, используя Tasklet вместо кусочно-ориентированного решения и добавив @Transactional к методу execute тасклета.

@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.SERIALIZABLE, noRollbackFor = {
        ErrorInternoServidorException.class, SolicitudIncorrectaException.class,
        RegistroNoEncontradoException.class, SolicitudEventoObjetaException.class,
        SolicitudEventoValidaException.class, MimCargueSolicitudException.class, ConflictException.class,
        UnauthorizedException.class, ForbiddenException.class }) 
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {

Ориентированное на фрагменты решение Spring Batch обернуто в тасклет с собственной транзакцией, поэтому я попытался создать новую со своими правилами.

Спасибо всем за ваши ответы. Я многому научился.

0 голосов
/ 03 мая 2020

Один из способов, которым вы могли бы написать свою JOB для фиксации всех ваших данных, даже когда в вашей обработке возникают исключения, - это использовать SkipPolicy и записать ваши данные в целевую БД там.

Одно из основных преимуществ SkipPolicy предназначен для регистрации данных, которые вызвали и исключение в процессе обработки, и часть ведения журнала может даже вставлять запись во временную таблицу в вашей БД.

public class FileVerificationSkipper implements SkipPolicy {

    private static final int MAX_VALUES_TO_SKIP = 1000;
    private JdbcTemplate jdbcTemplate;

    public FileVerificationSkipper(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @Override
    public boolean shouldSkip(Throwable exception, int skipCount) throws SkipLimitExceededException {
        if (exception instanceof FlatFileParseException && skipCount <= MAX_VALUES_TO_SKIP) {
            jdbcTemplate.update("INSERT INTO YourTable(column1, column2) VALUES(?,?)");
            return true;
        } else {
            return false;
        }
    }
}

Надеюсь, это поможет.

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