由于异常回滚后的Spring批量更新数据库状态
Posted
技术标签:
【中文标题】由于异常回滚后的Spring批量更新数据库状态【英文标题】:Spring batch update db status after rollback due to exception 【发布时间】:2020-11-16 13:49:17 【问题描述】:在 Spring 批处理 Writer 中,我将 db 行状态从 0 更新为 1。如果发生任何异常,则更新为 2。 但是由于@transaction 回滚,我无法将状态更新为 2。
(我抛出异常触发回滚)
@Override
@Transactional
public void write(List<? extends TestEntity> enityList) throws Exception
for(TestEntity testEntity : enityList)
try
testEntity.setStatus(2);
testRepository.save(testEntity);
testRepository.flush();
testMethod(testEntity); (which throws exception)
catch (Exception exception)
testEntity.setStatus(2);
testRepository.save(testEntity);
@Transactional
public void testMethod(TestEntity testEntity) throws Exception
try
//Some service call
//...
catch(Exception e)
log.error("error", e);
throw new Exception("exp");
【问题讨论】:
您的问题是“尽管事务被回滚,我如何存储数据?” 您需要单独的交易来更新状态。请给我看看Writer的代码吗 我尝试通过评论 write() 的@Transaction。还是不行 @dube 是的,这就是我想要的。 【参考方案1】:具有@Transactional
的方法会在抛出异常时回滚事务。因此,如果异常是您的代码的预期且正常的流程,则不应抛出异常并返回某种结果对象或状态代码。
@Transactional
public void testMethodThatIsAllowedToFail(TestEntity testEntity)
try
//Some service call
catch(Exception e)
return Status.FAILURE; // enum you have to create
return Status.SUCCESS;
// spring batch writer
public void write(List<? extends TestEntity> enityList) throws Exception
[...]
Status result = testMethod(testEntity); (which throws exception);
if (result != Status.SUCCESS)
// do something with it
[...]
您也可以使用@Transactional(propagation = Propagation.REQUIRES_NEW)
,但您必须认真考虑是否需要额外的交易。
【讨论】:
以上是关于由于异常回滚后的Spring批量更新数据库状态的主要内容,如果未能解决你的问题,请参考以下文章
在集成测试中每个方法不回滚后 Spring Data JPA 数据库更改
Spring Kafka - 事务回滚后重试时,通过侦听器容器事务发布消息和提交记录偏移失败