我在一个带注解的类@Transactional
中有一个作业方法。此作业方法调用内部方法以持久化单个记录。如果我在结果集处理的中间位置模拟以下内部update()
方法中的错误,我会看到此异常之前/之后的所有成功记录在作业完成后不会被保存。为什么会这样呢?所有外部持久性都应该保留,但失败的单个记录除外。仅内部的update
就有rollbackFor
。
@Service("mailService")
@Transactional
@EnableScheduling
public class MailServiceImpl implements MailService {
@Override
@Scheduled(cron = "${mail.cron.pubmed.autosynch.job}")
public void autoSynchPubMedJob() {
//... Fetch result set
for (Result r: resultset) {
try {
pubService.updatePublication(r);
} catch (Exception e) {
// Silently log and continue
log.error("Error on record: ", e);
}
}
}
updatePublication
方法,这是具有rollbackFor
的方法:
@Override
@Transactional(readOnly = false, rollbackFor = Exception.class)
public void updatePublication(Publication publication) throws Exception {
dao.update1(..);
dao.update2(..);
// Simulate exception for a specific record for testing
if (publication.getId() == 123) {
throw new Exception("Test Exception");
}
}
结果:在作业完成结束时,没有成功的数据持续存在。应该有部分持久性(对于其他成功的记录)。当我删除这个异常模拟时,所有数据都在最后成功持久化。此外,如果删除内部调用的rollbackFor
,则所有数据都将持久化。
1条答案
按热度按时间31moq8wy1#
ProBaby,因为它使用现有事务。尝试使用
propagation = REQUIRES_NEW
打开一个新的。注意:如果从同一服务调用该方法,则不会打开新的事务。您应该对另一个
@Service
使用自引用调用或提取逻辑。