Introduce resolvable timeout attribute on @Transactional and <tx:method>
Placeholders get resolved in timeoutString, qualifier and labels now. Closes gh-25052
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -69,6 +69,7 @@ public class TxNamespaceHandlerTests {
|
||||
assertThat(ptm.begun).as("Should not have any started transactions").isEqualTo(0);
|
||||
testBean.getName();
|
||||
assertThat(ptm.lastDefinition.isReadOnly()).isTrue();
|
||||
assertThat(ptm.lastDefinition.getTimeout()).isEqualTo(5);
|
||||
assertThat(ptm.begun).as("Should have 1 started transaction").isEqualTo(1);
|
||||
assertThat(ptm.commits).as("Should have 1 committed transaction").isEqualTo(1);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -140,22 +140,31 @@ public class AnnotationTransactionAttributeSourceTests {
|
||||
@Test
|
||||
public void transactionAttributeOnTargetClassMethodOverridesAttributeOnInterfaceMethod() throws Exception {
|
||||
Method interfaceMethod = ITestBean3.class.getMethod("getAge");
|
||||
Method interfaceMethod2 = ITestBean3.class.getMethod("getName");
|
||||
Method interfaceMethod2 = ITestBean3.class.getMethod("setAge", int.class);
|
||||
Method interfaceMethod3 = ITestBean3.class.getMethod("getName");
|
||||
|
||||
AnnotationTransactionAttributeSource atas = new AnnotationTransactionAttributeSource();
|
||||
atas.setEmbeddedValueResolver(strVal -> ("${myTimeout}".equals(strVal) ? "5" : strVal));
|
||||
|
||||
TransactionAttribute actual = atas.getTransactionAttribute(interfaceMethod, TestBean3.class);
|
||||
assertThat(actual.getPropagationBehavior()).isEqualTo(TransactionAttribute.PROPAGATION_REQUIRES_NEW);
|
||||
assertThat(actual.getIsolationLevel()).isEqualTo(TransactionAttribute.ISOLATION_REPEATABLE_READ);
|
||||
assertThat(actual.getTimeout()).isEqualTo(5);
|
||||
assertThat(actual.isReadOnly()).isTrue();
|
||||
|
||||
TransactionAttribute actual2 = atas.getTransactionAttribute(interfaceMethod2, TestBean3.class);
|
||||
assertThat(actual2.getPropagationBehavior()).isEqualTo(TransactionAttribute.PROPAGATION_REQUIRES_NEW);
|
||||
assertThat(actual2.getIsolationLevel()).isEqualTo(TransactionAttribute.ISOLATION_REPEATABLE_READ);
|
||||
assertThat(actual2.getTimeout()).isEqualTo(5);
|
||||
assertThat(actual2.isReadOnly()).isTrue();
|
||||
|
||||
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
|
||||
rbta.getRollbackRules().add(new RollbackRuleAttribute(Exception.class));
|
||||
rbta.getRollbackRules().add(new NoRollbackRuleAttribute(IOException.class));
|
||||
assertThat(((RuleBasedTransactionAttribute) actual).getRollbackRules()).isEqualTo(rbta.getRollbackRules());
|
||||
|
||||
TransactionAttribute actual2 = atas.getTransactionAttribute(interfaceMethod2, TestBean3.class);
|
||||
assertThat(actual2.getPropagationBehavior()).isEqualTo(TransactionAttribute.PROPAGATION_REQUIRED);
|
||||
TransactionAttribute actual3 = atas.getTransactionAttribute(interfaceMethod3, TestBean3.class);
|
||||
assertThat(actual3.getPropagationBehavior()).isEqualTo(TransactionAttribute.PROPAGATION_REQUIRED);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -585,6 +594,9 @@ public class AnnotationTransactionAttributeSourceTests {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation=Isolation.REPEATABLE_READ,
|
||||
timeoutString = "${myTimeout}", readOnly = true, rollbackFor = Exception.class,
|
||||
noRollbackFor = IOException.class)
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.transaction.annotation;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -31,13 +32,16 @@ import org.springframework.context.annotation.ConditionContext;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ConfigurationCondition;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionManager;
|
||||
import org.springframework.transaction.config.TransactionManagementConfigUtils;
|
||||
import org.springframework.transaction.event.TransactionalEventListenerFactory;
|
||||
import org.springframework.transaction.interceptor.TransactionAttribute;
|
||||
import org.springframework.transaction.testfixture.CallCountingTransactionManager;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -99,6 +103,9 @@ public class EnableTransactionManagementTests {
|
||||
assertThat(txManager.begun).isEqualTo(1);
|
||||
assertThat(txManager.commits).isEqualTo(1);
|
||||
assertThat(txManager.rollbacks).isEqualTo(0);
|
||||
assertThat(txManager.lastDefinition.isReadOnly()).isTrue();
|
||||
assertThat(txManager.lastDefinition.getTimeout()).isEqualTo(5);
|
||||
assertThat(((TransactionAttribute) txManager.lastDefinition).getLabels()).contains("LABEL");
|
||||
|
||||
ctx.close();
|
||||
}
|
||||
@@ -266,7 +273,7 @@ public class EnableTransactionManagementTests {
|
||||
@Service
|
||||
public static class TransactionalTestBean {
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
@Transactional(label = "${myLabel}", timeoutString = "${myTimeout}", readOnly = true)
|
||||
public Collection<?> findAllFoos() {
|
||||
return null;
|
||||
}
|
||||
@@ -275,14 +282,31 @@ public class EnableTransactionManagementTests {
|
||||
public void saveQualifiedFoo() {
|
||||
}
|
||||
|
||||
@Transactional(transactionManager = "qualifiedTransactionManager")
|
||||
@Transactional(transactionManager = "${myTransactionManager}")
|
||||
public void saveQualifiedFooWithAttributeAlias() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
static class PlaceholderConfig {
|
||||
|
||||
@Bean
|
||||
public PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
|
||||
PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
|
||||
Properties props = new Properties();
|
||||
props.setProperty("myLabel", "LABEL");
|
||||
props.setProperty("myTimeout", "5");
|
||||
props.setProperty("myTransactionManager", "qualifiedTransactionManager");
|
||||
pspc.setProperties(props);
|
||||
return pspc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@EnableTransactionManagement
|
||||
@Import(PlaceholderConfig.class)
|
||||
static class EnableTxConfig {
|
||||
}
|
||||
|
||||
@@ -294,6 +318,7 @@ public class EnableTransactionManagementTests {
|
||||
|
||||
@Configuration
|
||||
@EnableTransactionManagement
|
||||
@Import(PlaceholderConfig.class)
|
||||
@Conditional(NeverCondition.class)
|
||||
static class ParentEnableTxConfig {
|
||||
|
||||
@@ -433,6 +458,7 @@ public class EnableTransactionManagementTests {
|
||||
|
||||
@Configuration
|
||||
@EnableTransactionManagement
|
||||
@Import(PlaceholderConfig.class)
|
||||
static class Spr11915Config {
|
||||
|
||||
@Autowired
|
||||
|
||||
Reference in New Issue
Block a user