[英]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
中我的測試步驟(應用程序關閉后)的狀態為STARTED
且END_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.