Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring:对已检查的异常自动回滚_Java_Spring_Transactional - Fatal编程技术网

Java Spring:对已检查的异常自动回滚

Java Spring:对已检查的异常自动回滚,java,spring,transactional,Java,Spring,Transactional,将Spring配置为在非运行时异常上回滚的一种方法是在服务类上使用@Transactional(rollboor=…)注释。这种方法的问题是,我们需要为几乎所有看起来确实冗余的服务类定义(rollboor=…) 我的问题:是否有任何方法可以配置Spring事务管理器的默认行为,以便在非运行时异常发生时回滚,而不在每个@Transactional注释中声明它。类似于在EJB中的异常类上使用@ApplicationException(rollback=true)注释。对于应用程序级别的@Trans

将Spring配置为在非
运行时异常上回滚的一种方法是在服务类上使用
@Transactional(rollboor=…)
注释。这种方法的问题是,我们需要为几乎所有看起来确实冗余的服务类定义(rollboor=…)



我的问题:是否有任何方法可以配置Spring事务管理器的默认行为,以便在非
运行时异常发生时回滚,而不在每个
@Transactional
注释中声明它。类似于在EJB中的异常类上使用
@ApplicationException(rollback=true)
注释。

对于应用程序级别的@Transactional,您不能这样做,但您可以:

变量1:扩展@Transactional注释,并将其作为rollbackfor的默认值。但只在需要时设置rollbackFor unchecked异常。这样,您可以仅在确定的情况下控制回滚,并避免复制@Transactional(rollbackFor=MyCheckedException.class)的过去

比如:

并使用此注释而不是标准的@Transactional

变体2:您可以从以下方法创建扩展并重写方法determineTransactionAttribute:

protected TransactionAttribute  determineTransactionAttribute(AnnotatedElement ae)
//Determine the transaction attribute for the given method or class.
TransactionAttribute请参见,有一个方法

布尔回滚(Throwable ex)我们应该回滚给定的异常吗

}

第二种方法不如第一种方法好,因为对于事务管理器来说,它实际上是全局的。最好使用自定义注释,因为您可以对其进行任何控制,仅适用于您真正需要的方法/类。但如果您在任何情况下需要它,请使用第二个变体,这将是您的默认跨国行为

此配置解决了此问题:

@Configuration
public class MyProxyTransactionManagementConfiguration extends ProxyTransactionManagementConfiguration {

    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public TransactionAttributeSource transactionAttributeSource() {
        return new AnnotationTransactionAttributeSource() {

            @Nullable
            protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
                TransactionAttribute ta = super.determineTransactionAttribute(element);
                if (ta == null) {
                    return null;
                } else {
                    return new DelegatingTransactionAttribute(ta) {
                        @Override
                        public boolean rollbackOn(Throwable ex) {
                            return super.rollbackOn(ex) || ex instanceof Exception;
                        }
                    };
                }
            }
        };
    }
}

这是一种类似于的方法,即全局更改默认值,但对Spring配置的更改尽可能少,并且仍然可以像往常一样自定义每个方法的回滚规则(使用
rollboor
norollboor
等)

这只需为
Exception.class
添加默认回滚规则即可实现。由于规则根据异常类层次结构(适用于最特定异常类的规则)具有优先级,因此如果注释上未定义其他规则,则新规则的优先级基本上最低

@配置
公共类MyTransactionManagementConfiguration{
/**
*注意:与之相比,此自定义配置不识别{@code javax.transaction.Transactional}注释
*原始Spring行为。检查原始{@code AnnotationTransactionAttributeSource}源代码,了解如何添加它。
*
*@请参见AnnotationTransactionAttributeSource#AnnotationTransactionAttributeSource(布尔值)
*/
@豆子
@初级的
@角色(BeanDefinition.Role\u基础设施)
public TransactionAttributeSource transactionAttributeSourceWithDefaultRollBackForAllExceptions(){
返回新的注释TransactionAttributeSource(
新的SpringTransactionAnnotationParser(){
@凌驾
受保护的TransactionAttribute parseTransactionAnnotation(AnnotationAttributes属性){
RuleBasedTransactionAttribute rbta=(RuleBasedTransactionAttribute)super.parseTransactionAnnotation(属性);
列表规则=新的ArrayList(rbta.getRollbackRules());
添加(新的RollbackRuleAttribute(Exception.class));
rbta.setRollbackRules(规则);
返回rbta;
}
}
);
}
}

检查“回滚”部分:谢谢,扩展@Transactional annotation是个好主意。@xyz多年来我使用了第二个版本,但在spring boot 2.1/spring 5.1中它停止工作。没有错误,但是
@Transactional
的行为现在是通常的行为,而不是想要的行为t777 7分钟ago@xyz我正在考虑采用您的第二个变体,因为它会更容易,其他使用该代码的程序员不必考虑它。但我不想犯任何错误为什么不像第二个变体中提到的那样在全球范围内做这件事不是“那么好”?在某种情况下,不回滚已检查的异常是否有意义?我真的很好奇。提前谢谢!全球变化的最佳解决方案,谢谢@Nullable在我的项目中是未知的注释-它是什么spring版本?此外,将此配置类添加到我的项目中会阻止服务启动。由于NPE,它无法实例化BeanFactoryTransactionAttributeSourceVisor。知道为什么会这样吗?!Spring版本是5。查看堆栈跟踪以查看NPE的来源。
protected TransactionAttribute determineTransactionAttribute(
    AnnotatedElement ae) {
    return new DelegatingTransactionAttribute(target) {
        @Override
        public boolean rollbackOn(Throwable ex) {
           return (check is exception type as you need for rollback );
       }
};
@Configuration
public class MyProxyTransactionManagementConfiguration extends ProxyTransactionManagementConfiguration {

    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public TransactionAttributeSource transactionAttributeSource() {
        return new AnnotationTransactionAttributeSource() {

            @Nullable
            protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
                TransactionAttribute ta = super.determineTransactionAttribute(element);
                if (ta == null) {
                    return null;
                } else {
                    return new DelegatingTransactionAttribute(ta) {
                        @Override
                        public boolean rollbackOn(Throwable ex) {
                            return super.rollbackOn(ex) || ex instanceof Exception;
                        }
                    };
                }
            }
        };
    }
}