如果出现错误,我有一组操作我想要回滚。
我的班级
public class BSException extends RuntimeException{
...
}
public class saleFacade{
public update(){
for (){
try{
renewSale();
}
catch(BSException){
logger.error();
}
}
}
@Transactional
public renewSale(){
try{
findSale(); // read only Transactional
xxx.renewSpecialSale();
}
catch(Exception e){
logger.error(...);
}
}
}
public class xxx(){
public void renewSpecialSale(){
payFee(); //write to db
if(error){
throw new BSException();
}
}
@Transactional(propagation = Propagation.REQUIRED)
public payFee(){
try{
...
}
catch(BsException e){
...
}
catch(Exception e){
...
}
}
}
@Configuration
@EnableTransactionManagement
public class DBConfiguration{
@Bean(name = "dataSource")
public BasicDataSource dataSource(){
...
}
}
Inn renewSpecialSale错误是throw。
在renewSale方法中,如果有错误,我想回滚。 现在什么都没有回滚
任何想法?
答案 0 :(得分:2)
如果在它离开方法之前捕获异常,则包装方法的代理无法知道抛出异常。
完全删除try-catch或重新抛出异常,以便异常可以保留您标记为@Transactional的方法(并被代理拦截),并且将发生回滚。
我建议从所有这些方法中删除异常处理。设置一个中央异常处理程序,以便从控制器抛出的任何东西都被捕获并记录,否则会抛出异常。
确保每个执行事务的类都是单独注释的,如果在方法级别进行注释,那么应该对每个执行事务的方法进行注释。从同一对象上的非事务方法调用事务方法不会通过代理(代理只拦截来自对象外部的那些调用,并且只有当该方法被标记为事务时才这样)所以它不是'交易的一部分(+1到Peter's answer用于指出这一点。)
我不知道你的错误标志在做什么,这看起来很奇怪。 Spring服务不应该有状态。如果您修复了异常处理,则不需要错误标记。
答案 1 :(得分:1)
问题来自于您对Method调用的嵌套和@Transactional的使用。默认情况下,弹簧交易管理
在代理模式(默认设置)下,只拦截通过代理进入的外部方法调用。这意味着实际上,自调用目标对象中的一个方法调用目标对象的另一个方法,即使被调用的方法用@Transactional标记,也不会在运行时导致实际的事务。 Spring Transaction Management
这意味着,呼叫
xxx.payFee()
通过调用时,不会被事务包围
saleFacade.update() -> saleFacade.renewSale() -> xxx.renewSpecialSale()
据我所知,你至少有这些选项
答案 2 :(得分:0)
从您的方法中删除try catch块并将其放在下面的代码行
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
使用这行代码
@Transactional(propagation = Propagation.REQUIRED)
在上面的代码spring容器处理整个事务管理,如果我们提供rollback属性,它会自动管理是否发生任何类型的异常它会回滚你的事务
并确保您在配置文件中输入了事务,如下所示
<tx:annotation-driven />
以及
我希望它一定能帮到你
答案 3 :(得分:0)
此外,您可以创建自己的自定义异常类并将其抛出。
从标有RuntimeException
的方法中抛出任何@Transactional
。
默认情况下,所有RuntimeExceptions
回滚交易,而已检查的例外情况不适用。这是EJB的遗产。您可以使用rollbackFor()
和noRollbackFor()
注释参数进行配置:
@Transactional(rollbackFor=Exception.class)
这将在抛出任何异常后回滚事务。
@Transactional(rollbackFor = MyCheckedException.class)
public void foo() {
throw new RuntimeException();
}