异常捕获后的事务回滚

3

在使用声明式事务管理后,是否有任何方法可以在捕获异常后回滚事务。我有以下代码:

@Component
@Transactional(rollbackFor = EvictionException.class)
Public class Eviction{

@Autowired
private Alerter alerter;

@Scheduled(cron = "${evictor.cron.expression}")
public void evictObjectFromDatabase(){
try{
   ....
   DO SOME DELETION QUERIES
}catch(Exception ex){
   alerter.produceAlert("Failed to delete entries from database");
}
}
}

如果在删除过程中产生异常,我需要发出警报,让另一个团队监控swing UI。同时,我需要回滚事务,但使用rollBackFor = Exception.class无法实现。

你应该在哪里抛出被标记为 @TransactionalEvictionException 以进行回滚? - Daniel Olszewski
你能通过使用throws将异常从方法中抛出来吗?或者这不是一个选项吗? - Andy Dufresne
有没有办法在不重新抛出异常的情况下回滚事务? - Ambuj Jauhari
3个回答

7
您需要在方法上注释@Transactional(rollbackFor = Exception.class),在catch块中抛出异常(这样事务代理可以检测到异常,并进行回滚)。例如:
try{
   ....
   DO SOME DELETION QUERIES
}catch(Exception ex){
   alerter.produceAlert("Failed to delete entries from database");
   throw ex;// this is important
}

谢谢您的输入。我还想知道的是,如果我从这里抛出异常,它会被记录在我的日志文件中。如果发生许多这样的异常,它将填满我的日志,是否有任何解决方法,使得我的异常不会记录在我的日志文件中? - Ambuj Jauhari
我尝试使用@ Transactional(rollbackFor = Exception.class)进行注释,并使用throw ex。它撤销了我的事务。然后我尝试了不使用@ Transactional(rollbackFor = Exception.class)并使用throw ex,它也撤销了我的事务。那么使用rollbackFor的意义是什么?在这里感到困惑:( - Ambuj Jauhari
@AmbujJauhari 这里的区别在于,如果您抛出自定义异常,例如 throw new FooException(),那么只有 @Transactional(rollbackFor = Exception.class) 能够生效,因为 Spring 事务回滚遵循 EJB 约定。 - sol4me
@AmbujJauhari 你可以创建自己的自定义异常,并在throw子句中使用它,然后可以配置日志框架将这些异常记录在不同的日志文件中。或者,如果你不想记录任何内容,那么可以配置日志框架来排除它们的记录,但我个人更喜欢第一种方法,即将异常记录到单独的文件中。 - sol4me
@solme 区别在于,如果您抛出自定义异常,例如 throw new FooException(),那么只有 @Transactional(rollbackFor = Exception.class) 会起作用,因为 Spring 事务回滚遵循 EJB 约定。这部分是正确的。如果您的自定义异常扩展自 Exception,则必须提供 rollback 属性;但如果它扩展自 RuntimeException 并且您从 catch 块中抛出它,则无需提供 rollbackfor 属性。 - unknown

0

如果您查看@transactional的文档,您会发现回滚仅在出现错误或运行时异常时发生。在您的情况下,最有可能的是,当您没有为例外提供回滚时,回滚就会发生。这是因为抛出的异常是运行时异常而不是任何已检查的异常。如果抛出的异常类型是任何已检查的异常,则如果您没有为exception.class属性提供回滚,回滚将不会发生。


-1

使用 SqlTransaction 和 RollBack


1
你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接