【问题标题】:spring transaction timeout configurablespring事务超时可配置
【发布时间】:2019-06-06 15:37:16
【问题描述】:

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

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

【问题讨论】:

  • timeout = TIMEOUT,这里TIMEOUT是作为配置传递的,是一个变量,可以使用@Transactional(propagation = Propagation.REQUIRED, timeout = 10),还需要什么?
  • @Anurag Sharma 因为他想以编程方式设置超时,其值是从属性文件中读取的。然而java注解只允许属性是一个常量。

标签: java spring hibernate spring-transactions


【解决方案1】:

由于我们无法为 Java 注释属性分配变量值,因此要以编程方式设置 @Transactionaltimeout ,最好的办法是覆盖 AbstractPlatformTransactionManager#determineTimeout()

假设您使用JpaTransactionManager,新的管理器看起来像下面的代码。它允许为每个事务设置超时。我们可以使用TransactionDefinition的名字来标识一个事务,在Spring声明式事务的情况下,默认的名字是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)中读取值。


2020 年 6 月 25 日更新:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-08
    • 2016-08-20
    • 2015-10-15
    • 2019-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    相关资源
    最近更新 更多