【发布时间】:2019-01-21 07:39:34
【问题描述】:
我有方法:
@Transactional
public void importChargesRequest() {
...
for (Charge charge : charges) {
try {
Charge savedCharge = saveCharge(charge);
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
对于坚持每个Charge我调用内部方法:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public Charge saveCharge(Charge charge) {
return chargesRepository.saveAndFlush(charge);
}
如果saveCharge 方法抛出异常(在我的情况下是约束异常)我想写日志,并继续保留另一个实体。但是当我捕获异常时 - 我的外部事务回滚错误:
Transaction was marked for rollback only; cannot commit; nested exception is org.hibernate.TransactionException: Transaction was marked for rollback only; cannot commit
我需要打开事务并开始保存每个实体。如果某些实体无法保存异常 - 我需要记录此异常并继续保存另一个实体。当所有实体都将保存(或记录)时,我需要提交外部事务。但现在它回滚了。我该如何解决?
编辑:
我接受了 cmets 并将 REQUIRES_NEW 事务转移到另一个 bean:
@Service
public class TestService {
private final TestDao testDao;
public TestService(TestDao testDao) {
this.testDao = testDao;
}
@Transactional
public void saveTest() {
for (int i = 0; i < 100; i++) {
Test test = new Test();
if (i == 10 || i == 20) {
test.setName("123");
} else {
test.setName(UUID.randomUUID().toString());
}
testDao.save(test);
}
}
}
每个内部事务的另一个 bean:
@Slf4j
@Component
@Repository
public class TestDao {
@PersistenceContext
private EntityManager entityManager;
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void save(Test test) {
entityManager.persist(test);
}
}
当我第一次尝试保存时,数据库中有 20 行。每次下一次保存我都会得到 +10 行。名称有约束。当我收到错误时-事务已提交且不继续。每次保存后我等待 98 行。
【问题讨论】:
-
我不确定我是否理解您在编辑/附录中所说的内容。 “每次保存后我都会等待 98 行。” - 你的意思是说你在每次保存后期望 98 新行(除了第一行,它应该给出99 新行,因为第一个“123”情况是正确的)?如果您在第一次调用 saveTest 后看到 20 行新行,并且在每次下一次调用 saveTest 后又看到 10 行,这表明 TestDao.save(...) 方法实际上不是事务性的。您可以通过设置断点/记录异常并查看堆栈跟踪来测试吗?
标签: java spring spring-data-jpa spring-transactions