java - Spring Batch + JPA + PostgreSQL 当前事务被中止,命令被忽略直到事务块结束
问题描述
我面临以下示例中描述的问题。我正在使用 Spring Batch ItemWriter 将数据插入数据库。数据导入成功后,我还想将批处理状态插入到另一个表中。但是,如果之前有失败的查询,Postgres 不允许我这样做。
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.configuration.annotation.JobScope;
import org.springframework.batch.item.ItemWriter;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Component;
@JobScope
@Component
@Slf4j
public class CsvWriter implements ItemWriter<List<CsvEntity>> {
// these are org.springframework.data.jpa.repository.JpaRepository
DataRepository dataRepository;
BatchStatusRepository batchStatusRepository;
@Override
public void write(List<? extends List<DataEntity>> data) {
Long batchId = data.get(0).get(0).getBatchId(); // each data belongs to a batch with batch id;
try {
csvRepository.saveAll(data.get(0)); // save data
batchStatusRepository.save( // if data was ok, write status Ok
BatchStatusEntity.builder()
.batchId(batchId)
.status("Ok")
.build());
} catch (DataIntegrityViolationException e) { // if there is inconsistency in data (duplicates), I want to set an Error status
log.error("Duplicate entity", e);
batchStatusRepository.save( // this throws org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block
BatchStatusEntity.builder()
.batchId(batchId)
.status("Error")
.build());
}
}
}
据我了解,我需要回滚第一个事务,但我不知道如何。我试图用 将saveAll分成单独的方法@Transactional(value = "transactionManager", rollbackFor = DataIntegrityViolationException.class)
,但它没有用。
解决方案
推荐阅读
- python - 计算数据子集每列的 n 个值的平均值的问题
- javascript - 在 Firestore 云函数中,forEach 循环返回数据库中项目数的倍数
- git - 获取特定历史版本的 git 等效于 hg update 是什么?
- java - JAXB - 转换其中包含 XSD/命名空间引用的 XML 文件
- javascript - 从数组集合中删除子对象
- python - 如何从 python 停止 shell 脚本(运行无限循环)?
- php - Ubuntu 14.04:找不到包 php7.0-zip
- hyperledger-fabric - Hyperledger Fabric cli容器的作用
- firebase - Firestore 规则:如何根据包含它的文档的字段允许访问子集合?
- typescript - 如何将数据附加到 `from([urls])` 并使用 RxJS 进行动态处理