gpt4 book ai didi

java - 使用 JPA 存储库保留 Spring Batch ItemWriter 的问题

转载 作者:行者123 更新时间:2023-12-01 22:56:51 25 4
gpt4 key购买 nike

我的 Spring Batch ItemWriter 存在问题,该批处理依赖于 JPA 存储库来更新数据。

这里是:

@Component
public class MessagesDigestMailerItemWriter implements ItemWriter<UserAccount> {

private static final Logger log = LoggerFactory.getLogger(MessagesDigestMailerItemWriter.class);

@Autowired
private MessageRepository messageRepository;

@Autowired
private MailerService mailerService;

@Override
public void write(List<? extends UserAccount> userAccounts) throws Exception {
log.info("Mailing messages digests and updating messages notification statuses");

for (UserAccount userAccount : userAccounts) {
if (userAccount.isEmailNotification()) {
mailerService.mailMessagesDigest(userAccount);
}
for (Message message : userAccount.getReceivedMessages()) {
message.setNotificationSent(true);
messageRepository.save(message);//NOT SAVING!!
}
}
}
}

这是我的Step配置:

@Configuration
public class MailStepConfiguration {

@Autowired
private StepBuilderFactory stepBuilderFactory;

@Autowired
private EntityManagerFactory entityManagerFactory;

@Autowired
private MessagesDigestMailerItemWriter itemWriter;

@Bean
public Step messagesDigestMailingStep() {
return stepBuilderFactory.get("messagesDigestMailingStep")//
.<UserAccount, UserAccount> chunk(1)//
.reader(jpaPagingItemReader(entityManagerFactory))//
.writer(itemWriter)//
.build();
}

@Bean(destroyMethod = "")
@StepScope
public static ItemReader<UserAccount> jpaPagingItemReader(EntityManagerFactory entityManagerFactory) {
final JpaPagingItemReader<UserAccount> reader = new JpaPagingItemReader<>();
reader.setEntityManagerFactory(entityManagerFactory);
reader.setQueryString("SELECT ua FROM UserAccount ua JOIN FETCH ua.receivedMessages msg WHERE msg.notificationSent = false AND msg.messageRead = false");
return reader;
}

}

为了完整起见,这是我的 Spring Boot 配置:

@Configuration
@EnableBatchProcessing
@EnableAutoConfiguration
@ComponentScan("com.bignibou.batch.configuration")
public class Batch {
public static void main(String[] args) {
System.exit(SpringApplication.exit(new SpringApplicationBuilder(Batch.class).web(false).run(args)));
}
}

和我的数据源配置:

@Configuration
@EnableJpaRepositories({ "com.bignibou.repository" })
@EntityScan("com.bignibou.domain")
public class DatasourceConfiguration {

@Bean
@ConfigurationProperties("spring.datasource.batch")
public DataSource batchDatasource() {
return DataSourceBuilder.create().build();
}

@Bean
@Primary
@ConfigurationProperties("spring.datasource.application")
public DataSource applicationDatasource() {
return DataSourceBuilder.create().build();
}
}

我注意到执行流程进入了 ItemWriter 的 write 方法,并且 messageRepository.save(message); 确实被执行,但数据没有更新。

我怀疑这是一个交易问题,但我不知道如何解决这个问题...

编辑:我忘了提及我有两个 Postgres 数据库:

  1. 一个用于作业存储库数据
  2. 另一份用于应用程序数据。

我可以确认数据已写入作业存储库数据库。问题出在应用程序数据上。考虑到我有两个 PG 数据库,我需要使用分布式事务吗?

最佳答案

我在这里为此提出了一个问题:

https://jira.spring.io/browse/BATCH-2642

原则上,对我们有帮助的是配置​​主事务管理器,如下所示:

@Configuration
public class JpaConfig {

private final DataSource dataSource;

@Autowired
public JpaConfig(@Qualifier("dataSource") DataSource dataSource) {
this.dataSource = dataSource;
}

@Bean
@Primary
public JpaTransactionManager jpaTransactionManager() {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
}

}

然后在配置步骤时使用事务管理器的 Autowiring 实例,如下所示:

@Autowired
private PlatformTransactionManager transactionManager;

private TaskletStep buildTaskletStep() {
return stepBuilderFactory.get("SendCampaignStep")
.<UserAccount, UserAccount>chunk(pushServiceConfiguration.getCampaignBatchSize())
.reader(userAccountItemReader)
.processor(userAccountItemProcessor)
.writer(userAccountItemWriter)
.transactionManager(transactionManager)
.build();
}
}

数据现在已正确保存,但仍有一些魔力我没有完全理解......

关于java - 使用 JPA 存储库保留 Spring Batch ItemWriter 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38287298/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com