Прежде всего, вы должны исключить свою текущую аннотацию @EnableTransactionManagement
, которая будет активной в вашем профиле test
. Вы можете сделать это, выделив аннотацию @EnableTransactionManagement
на отдельный класс конфигурации, который исключает профиль test
, поэтому он активируется только тогда, когда профиль test
равен , а не.
@EnableTransactionManagement(mode=AdviceMode.PROXY)
@Profile("!test")
public class TransactionManagementConfig {}
С помощью этого на месте мы можем приступить к созданию пользовательской конфигурации управления транзакциями для вашего тестового профиля. Сначала мы определяем аннотацию, которая будет использоваться для активации пользовательского управления транзакциями (комментарии javadoc, снятые для компактности примера, см. В разделе EnableTransactionManagement
javadoc).
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(CustomTransactionManagementConfigurationSelector.class)
public @interface EnableCustomTransactionManagement {
boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY;
int order() default Ordered.LOWEST_PRECEDENCE;
}
Тогда нам нужен импортный селектор. Обратите внимание, что, поскольку вы используете AdviceMode.PROXY
, я пропустил реализацию части ASPECTJ
, но это должно быть сделано аналогичным образом, чтобы использовать управление транзакциями на основе AspectJ.
public class CustomTransactionManagementConfigurationSelector extends
AdviceModeImportSelector<EnableCustomTransactionManagement> {
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
return new String[] {
AutoProxyRegistrar.class.getName(),
CustomTransactionAttributeSourceConfig.class.getName()
};
case ASPECTJ:
default:
return null;
}
}
}
И, наконец, часть, в которой вы сможете переопределить атрибуты транзакции. В этом подклассе ProxyTransactionManagementConfiguration
для AdviceMode.PROXY
вам понадобится аналогичная реализация на основе AspectJTransactionManagementConfiguration
для AdviceMode.ASPECTJ
. Не стесняйтесь реализовать свою собственную логику, будь то постоянное переопределение любых атрибутов, которые исходный AnnotationTransactionAttributeSource
определял бы, как в моем примере, или увеличивая длину, путем введения и обработки вашей собственной аннотации для этой цели.
@Configuration
public class CustomTransactionAttributeSourceConfig
extends ProxyTransactionManagementConfiguration {
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
this.enableTx = AnnotationAttributes
.fromMap(importMetadata.getAnnotationAttributes(
EnableCustomTransactionManagement.class.getName(),
false));
Assert.notNull(this.enableTx,
"@EnableCustomTransactionManagement is not present on importing class "
+ importMetadata.getClassName());
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Override
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource() {
private static final long serialVersionUID = 1L;
@Override
protected TransactionAttribute findTransactionAttribute(
Class<?> clazz) {
TransactionAttribute transactionAttribute =
super.findTransactionAttribute(clazz);
if (transactionAttribute != null) {
// implement whatever logic to override transaction attributes
// extracted from @Transactional annotation
transactionAttribute = new DefaultTransactionAttribute(
TransactionAttribute.PROPAGATION_REQUIRED);
}
return transactionAttribute;
}
@Override
protected TransactionAttribute findTransactionAttribute(
Method method) {
TransactionAttribute transactionAttribute =
super.findTransactionAttribute(method);
if (transactionAttribute != null) {
// implement whatever logic to override transaction attributes
// extracted from @Transactional annotation
transactionAttribute = new DefaultTransactionAttribute(
TransactionAttribute.PROPAGATION_REQUIRED);
}
return transactionAttribute;
}
};
}
}
Наконец, вам необходимо включить конфигурацию управления пользовательских транзакций с классом конфигурации, привязанной к test
профилю.
@EnableCustomTransactionManagement(mode=AdviceMode.PROXY)
@Profile("test")
public class TransactionManagementTestConfig {}
Надеюсь, это поможет.
Вы используете 'AdviceMode.PROXY' или' AdviceMode.ASPECTJ' для управления транзакциями? –
Я использую по умолчанию 'AdviceMode.PROXY' – vhtc
. Что именно вы пытаетесь достичь? Другими словами, почему вы хотите, чтобы этот метод выполнялся в тестовой транзакции в тестах, но за пределами транзакции в производстве? –