簡體   English   中英

JOOQ 和 Spring Batch 事務管理

[英]JOOQ and Spring Batch transaction management

我目前正在開發 Spring Batch (2.6.3) 應用程序,我正在使用 JOOQ (3.14.15) 訪問 MariaDB 數據庫 (10.5.8)。 到目前為止,我只做了幾份工作,並達到了我正在測試交易的地步。 我正在嘗試運行 tasklet,據我所知,它默認在事務中執行。 我用簡單的插入創建了存儲庫,並用@Transactional進行了注釋。 我添加了Thread.sleep ,我的“測試用例”是讓 Spring Batch 執行我的測試小任務,並在睡眠期間殺死我的應用程序。 我預計T_FOO表中不會有記錄,因為我希望事務回滾,但我的T_FOO表中有記錄,即使在BATCH_STEP_EXECUTION中我的測試步驟(應用程序關閉后)的狀態為STARTEDEND_TIME設置為null - 我是猜測是在執行步驟時應用程序關閉時預期的表示。

我猜我沒有為 Spring Batch 和 JOOQ 或類似的東西設置正確的事務管理? 但這當然是錯誤的猜測

有人可以幫我解決這個問題嗎? 我試圖用谷歌搜索如何使用 Spring Batch 正確設置 JOOQ,但我能找到的唯一資源是這個資源,我寫了受那篇文章啟發的 jooq 配置,我也嘗試在文章中復制粘貼配置,但它沒有解決我的問題。

在此先感謝您的時間。


Tasklet 測試步驟

public Step testStep() {
        return this.stepBuilderFactory.get(TEST_STEP)
                .tasklet((stepContribution, chunkContext) -> {
                    final Integer batchId = JobUtils.getBatchId(chunkContext);
                    final LocalDateTime batchDate = JobUtils.getBatchDate(chunkContext);

                    importRepository.importBatch(batchId, batchDate);

                    /* Thread.sleep is here only for testing purposes - at this sleep I am shuting down application */
                    log.debug("Waiting start");
                    Thread.sleep(30000);
                    log.debug("Waiting end");

                    return RepeatStatus.FINISHED;
                }).listener(loadingProcessingErrorListener)
                .build();
    }

Transactional(propagation = Propagation.REQUIRED)
public void importBatch(@NonNull Integer batchId, @NonNull LocalDateTime batchDate) {
    /* simple insert select statement */
    context.insertInto(T_FOO)
        select(context.select(asterisk()).from(T_BAR))
        execute();
}

批量配置

@Configuration
@RequiredArgsConstructor
public class BatchConfiguration extends DefaultBatchConfigurer {

    private final JobRegistry jobRegistry;
    private final DataSource dataSource;

    @Override
    @NonNull
    @SneakyThrows
    public JobLauncher getJobLauncher() {
        SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
        jobLauncher.setJobRepository(getJobRepository());
        jobLauncher.setTaskExecutor(new SimpleAsyncTaskExecutor());
        jobLauncher.afterPropertiesSet();
        return jobLauncher;
    }

    @Bean
    public JobRegistryBeanPostProcessor jobRegistryBeanPostProcessor() {
        JobRegistryBeanPostProcessor postProcessor = new JobRegistryBeanPostProcessor();
        postProcessor.setJobRegistry(jobRegistry);
        return postProcessor;
    }

    @Override
    @NonNull
    public PlatformTransactionManager getTransactionManager() {
        return new DataSourceTransactionManager(dataSource);
    }
}

JOOQ 配置

@Configuration
@RequiredArgsConstructor
public class JooqConfiguration {

    private final DataSource dataSource;

    @Bean
    public DataSourceConnectionProvider connectionProvider() {
        return new DataSourceConnectionProvider(new TransactionAwareDataSourceProxy(dataSource));
    }

    @Bean
    public DefaultDSLContext context() {
        return new DefaultDSLContext(configuration());
    }

    public DefaultConfiguration configuration() {
        DefaultConfiguration jooqConfiguration = new DefaultConfiguration();

        jooqConfiguration.set(connectionProvider());

        jooqConfiguration.setDataSource(dataSource);
        jooqConfiguration.setSQLDialect(SQLDialect.MARIADB);
        jooqConfiguration.setSettings(new Settings().withExecuteWithOptimisticLocking(true));

        return jooqConfiguration;
    }
}

控制台日志

2022-05-28 21:26:18.571 DEBUG 15656 --- [cTaskExecutor-1] s.o.p.c.p.a.j.i.ImportLoadingSteps       : Starting loading import for Batch ID [1]
2022-05-28 21:26:18.607  INFO 15656 --- [cTaskExecutor-1] o.s.batch.core.job.SimpleStepHandler     : Executing step: [testStep]
2022-05-28 21:26:18.861 DEBUG 15656 --- [cTaskExecutor-1] org.jooq.tools.LoggerListener            : Executing query          : insert into `t_foo`...
2022-05-28 21:26:18.875 DEBUG 15656 --- [cTaskExecutor-1] org.jooq.tools.LoggerListener            : Affected row(s)          : 1
2022-05-28 21:26:18.876 DEBUG 15656 --- [cTaskExecutor-1] s.o.p.c.p.a.j.i.ImportLoadingSteps       : Waiting start
2022-05-28 21:26:23.759  INFO 15656 --- [ionShutdownHook] org.quartz.core.QuartzScheduler          : Scheduler quartzScheduler_$_NON_CLUSTERED paused.
2022-05-28 21:26:23.783  INFO 15656 --- [ionShutdownHook] o.s.s.quartz.SchedulerFactoryBean        : Shutting down Quartz Scheduler
2022-05-28 21:26:23.783  INFO 15656 --- [ionShutdownHook] org.quartz.core.QuartzScheduler          : Scheduler quartzScheduler_$_NON_CLUSTERED shutting down.
2022-05-28 21:26:23.783  INFO 15656 --- [ionShutdownHook] org.quartz.core.QuartzScheduler          : Scheduler quartzScheduler_$_NON_CLUSTERED paused.
2022-05-28 21:26:23.784  INFO 15656 --- [ionShutdownHook] org.quartz.core.QuartzScheduler          : Scheduler quartzScheduler_$_NON_CLUSTERED shutdown complete.
2022-05-28 21:26:23.790  INFO 15656 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...

Process finished with exit code -1

你這樣做:

jooqConfiguration.set(connectionProvider());

但是,你也不必要地這樣做:

jooqConfiguration.setDataSource(dataSource);

后者覆蓋前者,刪除TransactionAwareDataSourceProxy語義,否則也沒有其他用途。 只需刪除該呼叫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM