当前,我们在应用程序中面临与春季交易相关的问题。
如您所见,在deleteRecord()
中,我们正在执行数据库操作。但是在下一行
引发业务异常。
预期的行为(据我所知): 从下一行抛出异常时,应回滚数据库操作
实际行为: 它不会回滚。数据正在插入表中
问题:
为什么交易没有回滚?我不认为这是因为受阻
因为deleteRecord()
将在新事务中执行。如果我错了请纠正我
代码:
class A {
void myMethod() {
for(int i=0 ; i<count ; i++) {
try {
deleteRecord();
} catch(Exception e) {
log.error("Exception caught");
}
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
deleteRecord() throws Exception{
line 1 : deleting record
line 2 : Throwing business exception
}
}
答案 0 :(得分:2)
更改为
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
答案 1 :(得分:2)
Spring文档中的内容如下:
虽然EJB的默认行为是使EJB容器在系统异常(通常是运行时异常)时自动回滚事务,但是EJB CMT不会在应用程序异常(即已检查的异常)时自动回滚事务。除了java.rmi.RemoteException以外)。尽管Spring声明式事务管理的默认行为遵循EJB约定(仅针对未检查的异常会自动回滚),但自定义它通常很有用。
和
在默认配置下,Spring Framework的事务 在这种情况下,基础结构代码仅将事务标记为回滚 运行时,未经检查的异常;也就是说,当抛出异常时 是RuntimeException的实例或子类。 (错误还会- 默认情况下-会导致回滚)。引发的检查异常 从事务方法中获取默认值不会导致回滚 配置
请参见16.5.3:https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/transaction.html
这表示事务的默认行为将仅回滚RuntimeException
秒。如果您有自己的业务异常(可以是已检查的例外),则必须明确命名交易应回滚的异常类:
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = YOUREXCEPTION.class)
答案 2 :(得分:0)
这是因为同一类中的方法调用了@Transaction方法,如果未将Spring配置为使用AspectJ,则该方法不起作用。
Spring @Transaction method call by the method within the same class, does not work?