春季交易超时可配置 [英] spring transaction timeout configurable

查看:66
本文介绍了春季交易超时可配置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有固定超时的事务方法.有没有办法通过 application.yml 配置事务超时?

I have a transactional method which has a fixed timeout. Is there a way to make a transaction timeout configurable through i.e. an application.yml?

@Transactional(propagation = Propagation.REQUIRED, timeout = TIMEOUT)
public String doStuff(String id) throws Exception {
    service.doSomeStuff
}

推荐答案

由于我们无法将变量值分配给Java批注属性,因此需要以编程方式设置 @Transactional timeout ,最好的选择是重写 AbstractPlatformTransactionManager#determineTimeout().

As we cannot assign variable value to Java annotation attribute , to programmatically set @Transactional 's timeout , your best bet is to override AbstractPlatformTransactionManager#determineTimeout().

假设您使用的是 JpaTransactionManager ,新的管理器如下所示.它允许设置每个事务的超时时间.我们可以使用 TransactionDefinition 的名称来标识事务,对于Spring声明式事务,默认名称的格式为 FullyQualifiedClassName.MethodName .

Suppose you are using JpaTransactionManager, the new manager looks like the code below. It allows to set timeout per transaction. We can use TransactionDefinition 's name to identify a transaction ,which in case of Spring declarative transaction ,the default name is in the format of FullyQualifiedClassName.MethodName.

public class FooTransactionManager extends JpaTransactionManager {
    
    private Map<String, Integer> txTimeout = new HashMap<String, Integer>();

    public <T> void configureTxTimeout(Class<T> clazz, String methodName, Integer timeoutSecond) {
        txTimeout.put(clazz.getName() + "." + methodName, timeoutSecond);
    }

    //The timeout set by `configureTxTimeout` will have higher priority than the one set in @Transactional
    @Override
    protected int determineTimeout(TransactionDefinition definition) {;
        if (txTimeout.containsKey(definition.getName())) {
            return txTimeout.get(definition.getName());
        } else {
            return super.determineTimeout(definition);
        }
    }   
}

然后配置 PlatformTransactionManager :

@Bean
public PlatformTransactionManager transactionManager(final EntityManagerFactory emf) {
    final FooTransactionManager transactionManager = new FooTransactionManager();
    transactionManager.setEntityManagerFactory(emf);

    transactionManager.configureTxTimeout(Foo.class, "doStuff", 10);
    transactionManager.configureTxTimeout(Bar.class, "doStuff", 20);
    transactionManager.configureTxTimeout(Bar.class, "doMoreStuff", 30);
    //blablabla
    
    return transactionManager;
}

以上代码仅用于演示目的.实际上,您可以在配置过程中使用 @Value 从外部属性(例如 application.yml )中读取值.

The codes above is just for demonstration purpose . In reality , you can use @Value to read the value from an external properties (e.g application.yml) during the configuration.

2020年6月25日更新:

Update On 25-Jun-2020 :

  • 在即将到来的5.3中将提供开箱即用的支持(请参阅)

这篇关于春季交易超时可配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆