由于我们无法将变量值分配给Java注释属性,因此以编程方式设置@Transactional
's timeout
,你最好的选择是覆盖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 https://github.com/spring-projects/spring-framework/issues/25052)