Polishing
This commit is contained in:
parent
4a81814dbb
commit
6e5af9dccb
|
@ -60,8 +60,8 @@ class ScheduledAndTransactionalAnnotationIntegrationTests {
|
|||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
|
||||
ctx.register(Config.class, JdkProxyTxConfig.class, RepoConfigA.class);
|
||||
assertThatExceptionOfType(BeanCreationException.class)
|
||||
.isThrownBy(ctx::refresh)
|
||||
.withCauseInstanceOf(IllegalStateException.class);
|
||||
.isThrownBy(ctx::refresh)
|
||||
.withCauseInstanceOf(IllegalStateException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -70,7 +70,7 @@ class ScheduledAndTransactionalAnnotationIntegrationTests {
|
|||
ctx.register(Config.class, SubclassProxyTxConfig.class, RepoConfigA.class);
|
||||
ctx.refresh();
|
||||
|
||||
Thread.sleep(100); // allow @Scheduled method to be called several times
|
||||
Thread.sleep(200); // allow @Scheduled method to be called several times
|
||||
|
||||
MyRepository repository = ctx.getBean(MyRepository.class);
|
||||
CallCountingTransactionManager txManager = ctx.getBean(CallCountingTransactionManager.class);
|
||||
|
@ -85,7 +85,7 @@ class ScheduledAndTransactionalAnnotationIntegrationTests {
|
|||
ctx.register(Config.class, JdkProxyTxConfig.class, RepoConfigB.class);
|
||||
ctx.refresh();
|
||||
|
||||
Thread.sleep(100); // allow @Scheduled method to be called several times
|
||||
Thread.sleep(200); // allow @Scheduled method to be called several times
|
||||
|
||||
MyRepositoryWithScheduledMethod repository = ctx.getBean(MyRepositoryWithScheduledMethod.class);
|
||||
CallCountingTransactionManager txManager = ctx.getBean(CallCountingTransactionManager.class);
|
||||
|
@ -100,7 +100,7 @@ class ScheduledAndTransactionalAnnotationIntegrationTests {
|
|||
ctx.register(AspectConfig.class, MyRepositoryWithScheduledMethodImpl.class);
|
||||
ctx.refresh();
|
||||
|
||||
Thread.sleep(100); // allow @Scheduled method to be called several times
|
||||
Thread.sleep(200); // allow @Scheduled method to be called several times
|
||||
|
||||
MyRepositoryWithScheduledMethod repository = ctx.getBean(MyRepositoryWithScheduledMethod.class);
|
||||
assertThat(AopUtils.isCglibProxy(repository)).isTrue();
|
||||
|
|
|
@ -77,9 +77,7 @@ public class ThrowsAdviceInterceptorTests {
|
|||
given(mi.getMethod()).willReturn(Object.class.getMethod("hashCode"));
|
||||
given(mi.getThis()).willReturn(new Object());
|
||||
given(mi.proceed()).willThrow(ex);
|
||||
assertThatExceptionOfType(FileNotFoundException.class).isThrownBy(() ->
|
||||
ti.invoke(mi))
|
||||
.isSameAs(ex);
|
||||
assertThatExceptionOfType(FileNotFoundException.class).isThrownBy(() -> ti.invoke(mi)).isSameAs(ex);
|
||||
assertThat(th.getCalls()).isEqualTo(1);
|
||||
assertThat(th.getCalls("ioException")).isEqualTo(1);
|
||||
}
|
||||
|
@ -92,9 +90,7 @@ public class ThrowsAdviceInterceptorTests {
|
|||
ConnectException ex = new ConnectException("");
|
||||
MethodInvocation mi = mock();
|
||||
given(mi.proceed()).willThrow(ex);
|
||||
assertThatExceptionOfType(ConnectException.class).isThrownBy(() ->
|
||||
ti.invoke(mi))
|
||||
.isSameAs(ex);
|
||||
assertThatExceptionOfType(ConnectException.class).isThrownBy(() -> ti.invoke(mi)).isSameAs(ex);
|
||||
assertThat(th.getCalls()).isEqualTo(1);
|
||||
assertThat(th.getCalls("remoteException")).isEqualTo(1);
|
||||
}
|
||||
|
@ -117,9 +113,7 @@ public class ThrowsAdviceInterceptorTests {
|
|||
ConnectException ex = new ConnectException("");
|
||||
MethodInvocation mi = mock();
|
||||
given(mi.proceed()).willThrow(ex);
|
||||
assertThatExceptionOfType(Throwable.class).isThrownBy(() ->
|
||||
ti.invoke(mi))
|
||||
.isSameAs(t);
|
||||
assertThatExceptionOfType(Throwable.class).isThrownBy(() -> ti.invoke(mi)).isSameAs(t);
|
||||
assertThat(th.getCalls()).isEqualTo(1);
|
||||
assertThat(th.getCalls("remoteException")).isEqualTo(1);
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@ class QuartzSupportTests {
|
|||
trigger.setName("myTrigger");
|
||||
trigger.setJobDetail(jobDetail);
|
||||
trigger.setStartDelay(1);
|
||||
trigger.setRepeatInterval(500);
|
||||
trigger.setRepeatInterval(100);
|
||||
trigger.setRepeatCount(1);
|
||||
trigger.afterPropertiesSet();
|
||||
|
||||
|
@ -133,7 +133,7 @@ class QuartzSupportTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
void jobDetailWithRunnableInsteadOfJob() {
|
||||
JobDetailImpl jobDetail = new JobDetailImpl();
|
||||
assertThatIllegalArgumentException().isThrownBy(() ->
|
||||
|
@ -156,7 +156,7 @@ class QuartzSupportTests {
|
|||
trigger.setName("myTrigger");
|
||||
trigger.setJobDetail(jobDetail);
|
||||
trigger.setStartDelay(1);
|
||||
trigger.setRepeatInterval(500);
|
||||
trigger.setRepeatInterval(100);
|
||||
trigger.setRepeatCount(1);
|
||||
trigger.afterPropertiesSet();
|
||||
|
||||
|
@ -190,7 +190,7 @@ class QuartzSupportTests {
|
|||
trigger.setName("myTrigger");
|
||||
trigger.setJobDetail(jobDetail);
|
||||
trigger.setStartDelay(1);
|
||||
trigger.setRepeatInterval(500);
|
||||
trigger.setRepeatInterval(100);
|
||||
trigger.setRepeatCount(1);
|
||||
trigger.afterPropertiesSet();
|
||||
|
||||
|
@ -225,7 +225,7 @@ class QuartzSupportTests {
|
|||
trigger.setName("myTrigger");
|
||||
trigger.setJobDetail(jobDetail);
|
||||
trigger.setStartDelay(1);
|
||||
trigger.setRepeatInterval(500);
|
||||
trigger.setRepeatInterval(100);
|
||||
trigger.setRepeatCount(1);
|
||||
trigger.afterPropertiesSet();
|
||||
|
||||
|
@ -260,7 +260,7 @@ class QuartzSupportTests {
|
|||
trigger.setName("myTrigger");
|
||||
trigger.setJobDetail(jobDetail);
|
||||
trigger.setStartDelay(1);
|
||||
trigger.setRepeatInterval(500);
|
||||
trigger.setRepeatInterval(100);
|
||||
trigger.setRepeatCount(1);
|
||||
trigger.afterPropertiesSet();
|
||||
|
||||
|
|
|
@ -329,8 +329,8 @@ public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateCo
|
|||
* @return {@code true} if the bean can be registered as-is;
|
||||
* {@code false} if it should be skipped because there is an
|
||||
* existing, compatible bean definition for the specified name
|
||||
* @throws ConflictingBeanDefinitionException if an existing, incompatible
|
||||
* bean definition has been found for the specified name
|
||||
* @throws IllegalStateException if an existing, incompatible bean definition
|
||||
* has been found for the specified name
|
||||
*/
|
||||
protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) throws IllegalStateException {
|
||||
if (!this.registry.containsBeanDefinition(beanName)) {
|
||||
|
@ -354,16 +354,16 @@ public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateCo
|
|||
* the given existing bean definition.
|
||||
* <p>The default implementation considers them as compatible when the existing
|
||||
* bean definition comes from the same source or from a non-scanning source.
|
||||
* @param newDefinition the new bean definition, originated from scanning
|
||||
* @param existingDefinition the existing bean definition, potentially an
|
||||
* @param newDef the new bean definition, originated from scanning
|
||||
* @param existingDef the existing bean definition, potentially an
|
||||
* explicitly defined one or a previously generated one from scanning
|
||||
* @return whether the definitions are considered as compatible, with the
|
||||
* new definition to be skipped in favor of the existing definition
|
||||
*/
|
||||
protected boolean isCompatible(BeanDefinition newDefinition, BeanDefinition existingDefinition) {
|
||||
return (!(existingDefinition instanceof ScannedGenericBeanDefinition) || // explicitly registered overriding bean
|
||||
(newDefinition.getSource() != null && newDefinition.getSource().equals(existingDefinition.getSource())) || // scanned same file twice
|
||||
newDefinition.equals(existingDefinition)); // scanned equivalent class twice
|
||||
protected boolean isCompatible(BeanDefinition newDef, BeanDefinition existingDef) {
|
||||
return (!(existingDef instanceof ScannedGenericBeanDefinition) || // explicitly registered overriding bean
|
||||
(newDef.getSource() != null && newDef.getSource().equals(existingDef.getSource())) || // scanned same file twice
|
||||
newDef.equals(existingDef)); // scanned equivalent class twice
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -197,6 +197,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
context.registerBeanDefinition("stubFooDao", new RootBeanDefinition(TestBean.class));
|
||||
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
|
||||
scanner.setIncludeAnnotationConfig(false);
|
||||
|
||||
// should not fail!
|
||||
scanner.scan(BASE_PACKAGE);
|
||||
}
|
||||
|
@ -207,6 +208,7 @@ public class ClassPathBeanDefinitionScannerTests {
|
|||
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
|
||||
scanner.setIncludeAnnotationConfig(false);
|
||||
scanner.scan("org.springframework.context.annotation3");
|
||||
|
||||
assertThatIllegalStateException().isThrownBy(() -> scanner.scan(BASE_PACKAGE))
|
||||
.withMessageContaining("stubFooDao")
|
||||
.withMessageContaining(StubFooDao.class.getName());
|
||||
|
|
|
@ -24,8 +24,6 @@ import java.util.concurrent.CompletionStage;
|
|||
import java.util.concurrent.Flow;
|
||||
import java.util.function.Function;
|
||||
|
||||
import kotlinx.coroutines.CompletableDeferredKt;
|
||||
import kotlinx.coroutines.Deferred;
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.adapter.JdkFlowAdapter;
|
||||
import reactor.blockhound.BlockHound;
|
||||
|
@ -38,13 +36,14 @@ import org.springframework.util.ClassUtils;
|
|||
import org.springframework.util.ConcurrentReferenceHashMap;
|
||||
|
||||
/**
|
||||
* A registry of adapters to adapt Reactive Streams {@link Publisher} to/from
|
||||
* various async/reactive types such as {@code CompletableFuture}, RxJava
|
||||
* {@code Flowable}, and others.
|
||||
* A registry of adapters to adapt Reactive Streams {@link Publisher} to/from various
|
||||
* async/reactive types such as {@code CompletableFuture}, RxJava {@code Flowable}, etc.
|
||||
* This is designed to complement Spring's Reactor {@code Mono}/{@code Flux} support while
|
||||
* also being usable without Reactor, e.g. just for {@code org.reactivestreams} bridging.
|
||||
*
|
||||
* <p>By default, depending on classpath availability, adapters are registered
|
||||
* for Reactor, RxJava 3, {@link CompletableFuture}, {@code Flow.Publisher},
|
||||
* and Kotlin Coroutines' {@code Deferred} and {@code Flow}.
|
||||
* <p>By default, depending on classpath availability, adapters are registered for Reactor
|
||||
* (including {@code CompletableFuture} and {@code Flow.Publisher} adapters), RxJava 3,
|
||||
* Kotlin Coroutines' {@code Deferred} (bridged via Reactor) and SmallRye Mutiny 1.x.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Sebastien Deleuze
|
||||
|
@ -304,9 +303,9 @@ public class ReactiveAdapterRegistry {
|
|||
@SuppressWarnings("KotlinInternalInJava")
|
||||
void registerAdapters(ReactiveAdapterRegistry registry) {
|
||||
registry.registerReactiveType(
|
||||
ReactiveTypeDescriptor.singleOptionalValue(Deferred.class,
|
||||
() -> CompletableDeferredKt.CompletableDeferred(null)),
|
||||
source -> CoroutinesUtils.deferredToMono((Deferred<?>) source),
|
||||
ReactiveTypeDescriptor.singleOptionalValue(kotlinx.coroutines.Deferred.class,
|
||||
() -> kotlinx.coroutines.CompletableDeferredKt.CompletableDeferred(null)),
|
||||
source -> CoroutinesUtils.deferredToMono((kotlinx.coroutines.Deferred<?>) source),
|
||||
source -> CoroutinesUtils.monoToDeferred(Mono.from(source)));
|
||||
|
||||
registry.registerReactiveType(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
|
@ -37,7 +37,7 @@ public final class ReactiveTypeDescriptor {
|
|||
private final boolean noValue;
|
||||
|
||||
@Nullable
|
||||
private final Supplier<?> emptyValueSupplier;
|
||||
private final Supplier<?> emptySupplier;
|
||||
|
||||
private final boolean deferred;
|
||||
|
||||
|
@ -55,7 +55,7 @@ public final class ReactiveTypeDescriptor {
|
|||
this.reactiveType = reactiveType;
|
||||
this.multiValue = multiValue;
|
||||
this.noValue = noValue;
|
||||
this.emptyValueSupplier = emptySupplier;
|
||||
this.emptySupplier = emptySupplier;
|
||||
this.deferred = deferred;
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ public final class ReactiveTypeDescriptor {
|
|||
* Return {@code true} if the reactive type can complete with no values.
|
||||
*/
|
||||
public boolean supportsEmpty() {
|
||||
return (this.emptyValueSupplier != null);
|
||||
return (this.emptySupplier != null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -97,8 +97,8 @@ public final class ReactiveTypeDescriptor {
|
|||
* <p>Use of this type implies {@link #supportsEmpty()} is {@code true}.
|
||||
*/
|
||||
public Object getEmptyValue() {
|
||||
Assert.state(this.emptyValueSupplier != null, "Empty values not supported");
|
||||
return this.emptyValueSupplier.get();
|
||||
Assert.state(this.emptySupplier != null, "Empty values not supported");
|
||||
return this.emptySupplier.get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.time.Duration;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Flow;
|
||||
|
||||
import io.smallrye.mutiny.Multi;
|
||||
import io.smallrye.mutiny.Uni;
|
||||
|
@ -27,6 +28,7 @@ import kotlinx.coroutines.Deferred;
|
|||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.adapter.JdkFlowAdapter;
|
||||
import reactor.core.CoreSubscriber;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
@ -112,6 +114,16 @@ class ReactiveAdapterRegistryTests {
|
|||
assertThat(((Mono<Integer>) target).block(ONE_SECOND)).isEqualTo(Integer.valueOf(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void toFlowPublisher() {
|
||||
List<Integer> sequence = Arrays.asList(1, 2, 3);
|
||||
Publisher<Integer> source = io.reactivex.rxjava3.core.Flowable.fromIterable(sequence);
|
||||
Object target = getAdapter(Flow.Publisher.class).fromPublisher(source);
|
||||
assertThat(target).isInstanceOf(Flow.Publisher.class);
|
||||
assertThat(JdkFlowAdapter.flowPublisherToFlux((Flow.Publisher<Integer>) target)
|
||||
.collectList().block(ONE_SECOND)).isEqualTo(sequence);
|
||||
}
|
||||
|
||||
@Test
|
||||
void toCompletableFuture() throws Exception {
|
||||
Publisher<Integer> source = Flux.fromArray(new Integer[] {1, 2, 3});
|
||||
|
|
|
@ -88,8 +88,7 @@ class R2dbcTransactionManagerUnitTests {
|
|||
|
||||
ConnectionFactoryUtils.getConnection(connectionFactoryMock)
|
||||
.flatMap(connection -> TransactionSynchronizationManager.forCurrentTransaction()
|
||||
.doOnNext(synchronizationManager -> synchronizationManager.registerSynchronization(
|
||||
sync)))
|
||||
.doOnNext(synchronizationManager -> synchronizationManager.registerSynchronization(sync)))
|
||||
.as(operator::transactional)
|
||||
.as(StepVerifier::create)
|
||||
.expectNextCount(1)
|
||||
|
@ -120,12 +119,11 @@ class R2dbcTransactionManagerUnitTests {
|
|||
|
||||
TransactionalOperator operator = TransactionalOperator.create(tm, definition);
|
||||
|
||||
ConnectionFactoryUtils.getConnection(connectionFactoryMock).as(
|
||||
operator::transactional)
|
||||
ConnectionFactoryUtils.getConnection(connectionFactoryMock)
|
||||
.as(operator::transactional)
|
||||
.as(StepVerifier::create)
|
||||
.expectErrorSatisfies(actual -> assertThat(actual).isInstanceOf(
|
||||
CannotCreateTransactionException.class).hasCauseInstanceOf(
|
||||
R2dbcBadGrammarException.class))
|
||||
CannotCreateTransactionException.class).hasCauseInstanceOf(R2dbcBadGrammarException.class))
|
||||
.verify();
|
||||
}
|
||||
|
||||
|
@ -141,8 +139,8 @@ class R2dbcTransactionManagerUnitTests {
|
|||
|
||||
TransactionalOperator operator = TransactionalOperator.create(tm, definition);
|
||||
|
||||
ConnectionFactoryUtils.getConnection(connectionFactoryMock).as(
|
||||
operator::transactional)
|
||||
ConnectionFactoryUtils.getConnection(connectionFactoryMock)
|
||||
.as(operator::transactional)
|
||||
.as(StepVerifier::create)
|
||||
.expectNextCount(1)
|
||||
.verifyComplete();
|
||||
|
@ -171,8 +169,8 @@ class R2dbcTransactionManagerUnitTests {
|
|||
|
||||
TransactionalOperator operator = TransactionalOperator.create(tm, definition);
|
||||
|
||||
ConnectionFactoryUtils.getConnection(connectionFactoryMock).as(
|
||||
operator::transactional)
|
||||
ConnectionFactoryUtils.getConnection(connectionFactoryMock)
|
||||
.as(operator::transactional)
|
||||
.as(StepVerifier::create)
|
||||
.expectNextCount(1)
|
||||
.verifyComplete();
|
||||
|
@ -190,8 +188,8 @@ class R2dbcTransactionManagerUnitTests {
|
|||
|
||||
TransactionalOperator operator = TransactionalOperator.create(tm, definition);
|
||||
|
||||
ConnectionFactoryUtils.getConnection(connectionFactoryMock).as(
|
||||
operator::transactional)
|
||||
ConnectionFactoryUtils.getConnection(connectionFactoryMock)
|
||||
.as(operator::transactional)
|
||||
.as(StepVerifier::create)
|
||||
.expectNextCount(1)
|
||||
.verifyComplete();
|
||||
|
@ -215,8 +213,8 @@ class R2dbcTransactionManagerUnitTests {
|
|||
|
||||
TransactionalOperator operator = TransactionalOperator.create(tm, definition);
|
||||
|
||||
ConnectionFactoryUtils.getConnection(connectionFactoryMock).as(
|
||||
operator::transactional)
|
||||
ConnectionFactoryUtils.getConnection(connectionFactoryMock)
|
||||
.as(operator::transactional)
|
||||
.as(StepVerifier::create)
|
||||
.expectNextCount(1)
|
||||
.verifyComplete();
|
||||
|
@ -262,11 +260,9 @@ class R2dbcTransactionManagerUnitTests {
|
|||
TransactionalOperator operator = TransactionalOperator.create(tm);
|
||||
|
||||
ConnectionFactoryUtils.getConnection(connectionFactoryMock)
|
||||
.doOnNext(connection -> {
|
||||
throw new IllegalStateException();
|
||||
}).as(operator::transactional)
|
||||
.as(StepVerifier::create)
|
||||
.verifyError(IllegalStateException.class);
|
||||
.doOnNext(connection -> { throw new IllegalStateException(); })
|
||||
.as(operator::transactional)
|
||||
.as(StepVerifier::create).verifyError(IllegalStateException.class);
|
||||
|
||||
assertThat(commits).hasValue(0);
|
||||
assertThat(rollbacks).hasValue(1);
|
||||
|
@ -286,8 +282,7 @@ class R2dbcTransactionManagerUnitTests {
|
|||
reactiveTransaction.setRollbackOnly();
|
||||
return ConnectionFactoryUtils.getConnection(connectionFactoryMock)
|
||||
.doOnNext(connection -> connection.createStatement("foo")).then();
|
||||
}).as(StepVerifier::create)
|
||||
.verifyError(BadSqlGrammarException.class);
|
||||
}).as(StepVerifier::create).verifyError(BadSqlGrammarException.class);
|
||||
|
||||
verify(connectionMock).beginTransaction(any(io.r2dbc.spi.TransactionDefinition.class));
|
||||
verify(connectionMock).createStatement("foo");
|
||||
|
@ -308,7 +303,7 @@ class R2dbcTransactionManagerUnitTests {
|
|||
.doOnNext(connection -> {
|
||||
throw new IllegalStateException("Intentional error to trigger rollback");
|
||||
}).then()).as(StepVerifier::create)
|
||||
.verifyErrorSatisfies(e -> assertThat(e)
|
||||
.verifyErrorSatisfies(ex -> assertThat(ex)
|
||||
.isInstanceOf(BadSqlGrammarException.class)
|
||||
.hasCause(new R2dbcBadGrammarException("Rollback should fail"))
|
||||
);
|
||||
|
@ -334,8 +329,7 @@ class R2dbcTransactionManagerUnitTests {
|
|||
assertThat(synchronizationManager.hasResource(connectionFactoryMock)).isTrue();
|
||||
synchronizationManager.registerSynchronization(sync);
|
||||
}).then();
|
||||
}).as(StepVerifier::create)
|
||||
.verifyComplete();
|
||||
}).as(StepVerifier::create).verifyComplete();
|
||||
|
||||
verify(connectionMock).beginTransaction(any(io.r2dbc.spi.TransactionDefinition.class));
|
||||
verify(connectionMock).rollbackTransaction();
|
||||
|
@ -363,8 +357,7 @@ class R2dbcTransactionManagerUnitTests {
|
|||
fail("Should have thrown IllegalTransactionStateException");
|
||||
return Mono.empty();
|
||||
});
|
||||
}).as(StepVerifier::create)
|
||||
.verifyError(IllegalTransactionStateException.class);
|
||||
}).as(StepVerifier::create).verifyError(IllegalTransactionStateException.class);
|
||||
|
||||
verify(connectionMock).rollbackTransaction();
|
||||
verify(connectionMock).close();
|
||||
|
@ -381,14 +374,13 @@ class R2dbcTransactionManagerUnitTests {
|
|||
|
||||
TransactionalOperator operator = TransactionalOperator.create(tm, definition);
|
||||
operator.execute(tx1 -> {
|
||||
assertThat(tx1.isNewTransaction()).isTrue();
|
||||
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
|
||||
return operator.execute(tx2 -> {
|
||||
assertThat(tx2.isNewTransaction()).isTrue();
|
||||
return Mono.empty();
|
||||
});
|
||||
}).as(StepVerifier::create)
|
||||
.verifyComplete();
|
||||
assertThat(tx1.isNewTransaction()).isTrue();
|
||||
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
|
||||
return operator.execute(tx2 -> {
|
||||
assertThat(tx2.isNewTransaction()).isTrue();
|
||||
return Mono.empty();
|
||||
});
|
||||
}).as(StepVerifier::create).verifyComplete();
|
||||
|
||||
verify(connectionMock).createSavepoint("SAVEPOINT_1");
|
||||
verify(connectionMock).releaseSavepoint("SAVEPOINT_1");
|
||||
|
@ -407,15 +399,14 @@ class R2dbcTransactionManagerUnitTests {
|
|||
|
||||
TransactionalOperator operator = TransactionalOperator.create(tm, definition);
|
||||
operator.execute(tx1 -> {
|
||||
assertThat(tx1.isNewTransaction()).isTrue();
|
||||
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
|
||||
return operator.execute(tx2 -> {
|
||||
assertThat(tx2.isNewTransaction()).isTrue();
|
||||
tx2.setRollbackOnly();
|
||||
return Mono.empty();
|
||||
});
|
||||
}).as(StepVerifier::create)
|
||||
.verifyComplete();
|
||||
assertThat(tx1.isNewTransaction()).isTrue();
|
||||
definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
|
||||
return operator.execute(tx2 -> {
|
||||
assertThat(tx2.isNewTransaction()).isTrue();
|
||||
tx2.setRollbackOnly();
|
||||
return Mono.empty();
|
||||
});
|
||||
}).as(StepVerifier::create).verifyComplete();
|
||||
|
||||
verify(connectionMock).createSavepoint("SAVEPOINT_1");
|
||||
verify(connectionMock).rollbackTransactionToSavepoint("SAVEPOINT_1");
|
||||
|
@ -432,16 +423,15 @@ class R2dbcTransactionManagerUnitTests {
|
|||
|
||||
TransactionalOperator operator = TransactionalOperator.create(tm, definition);
|
||||
operator.execute(tx1 -> {
|
||||
assertThat(tx1.isNewTransaction()).isFalse();
|
||||
DefaultTransactionDefinition innerDef = new DefaultTransactionDefinition();
|
||||
innerDef.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
|
||||
TransactionalOperator inner = TransactionalOperator.create(tm, innerDef);
|
||||
return inner.execute(tx2 -> {
|
||||
assertThat(tx2.isNewTransaction()).isTrue();
|
||||
return Mono.empty();
|
||||
});
|
||||
}).as(StepVerifier::create)
|
||||
.verifyComplete();
|
||||
assertThat(tx1.isNewTransaction()).isFalse();
|
||||
DefaultTransactionDefinition innerDef = new DefaultTransactionDefinition();
|
||||
innerDef.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
|
||||
TransactionalOperator inner = TransactionalOperator.create(tm, innerDef);
|
||||
return inner.execute(tx2 -> {
|
||||
assertThat(tx2.isNewTransaction()).isTrue();
|
||||
return Mono.empty();
|
||||
});
|
||||
}).as(StepVerifier::create).verifyComplete();
|
||||
|
||||
verify(connectionMock).commitTransaction();
|
||||
verify(connectionMock).close();
|
||||
|
@ -456,17 +446,16 @@ class R2dbcTransactionManagerUnitTests {
|
|||
|
||||
TransactionalOperator operator = TransactionalOperator.create(tm, definition);
|
||||
operator.execute(tx1 -> {
|
||||
assertThat(tx1.isNewTransaction()).isFalse();
|
||||
DefaultTransactionDefinition innerDef = new DefaultTransactionDefinition();
|
||||
innerDef.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
|
||||
TransactionalOperator inner = TransactionalOperator.create(tm, innerDef);
|
||||
return inner.execute(tx2 -> {
|
||||
assertThat(tx2.isNewTransaction()).isTrue();
|
||||
tx2.setRollbackOnly();
|
||||
return Mono.empty();
|
||||
});
|
||||
}).as(StepVerifier::create)
|
||||
.verifyComplete();
|
||||
assertThat(tx1.isNewTransaction()).isFalse();
|
||||
DefaultTransactionDefinition innerDef = new DefaultTransactionDefinition();
|
||||
innerDef.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
|
||||
TransactionalOperator inner = TransactionalOperator.create(tm, innerDef);
|
||||
return inner.execute(tx2 -> {
|
||||
assertThat(tx2.isNewTransaction()).isTrue();
|
||||
tx2.setRollbackOnly();
|
||||
return Mono.empty();
|
||||
});
|
||||
}).as(StepVerifier::create).verifyComplete();
|
||||
|
||||
verify(connectionMock).rollbackTransaction();
|
||||
verify(connectionMock).close();
|
||||
|
@ -489,8 +478,7 @@ class R2dbcTransactionManagerUnitTests {
|
|||
assertThat(tx2.isNewTransaction()).isTrue();
|
||||
return Mono.empty();
|
||||
});
|
||||
}).as(StepVerifier::create)
|
||||
.verifyComplete();
|
||||
}).as(StepVerifier::create).verifyComplete();
|
||||
|
||||
verify(connectionMock).commitTransaction();
|
||||
verify(connectionMock).close();
|
||||
|
@ -505,17 +493,16 @@ class R2dbcTransactionManagerUnitTests {
|
|||
|
||||
TransactionalOperator operator = TransactionalOperator.create(tm, definition);
|
||||
operator.execute(tx1 -> {
|
||||
assertThat(tx1.isNewTransaction()).isFalse();
|
||||
DefaultTransactionDefinition innerDef = new DefaultTransactionDefinition();
|
||||
innerDef.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
||||
TransactionalOperator inner = TransactionalOperator.create(tm, innerDef);
|
||||
return inner.execute(tx2 -> {
|
||||
assertThat(tx2.isNewTransaction()).isTrue();
|
||||
tx2.setRollbackOnly();
|
||||
return Mono.empty();
|
||||
});
|
||||
}).as(StepVerifier::create)
|
||||
.verifyComplete();
|
||||
assertThat(tx1.isNewTransaction()).isFalse();
|
||||
DefaultTransactionDefinition innerDef = new DefaultTransactionDefinition();
|
||||
innerDef.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
||||
TransactionalOperator inner = TransactionalOperator.create(tm, innerDef);
|
||||
return inner.execute(tx2 -> {
|
||||
assertThat(tx2.isNewTransaction()).isTrue();
|
||||
tx2.setRollbackOnly();
|
||||
return Mono.empty();
|
||||
});
|
||||
}).as(StepVerifier::create).verifyComplete();
|
||||
|
||||
verify(connectionMock).rollbackTransaction();
|
||||
verify(connectionMock).close();
|
||||
|
|
|
@ -68,8 +68,7 @@ public interface PlatformTransactionManager extends TransactionManager {
|
|||
* @see TransactionDefinition#getTimeout
|
||||
* @see TransactionDefinition#isReadOnly
|
||||
*/
|
||||
TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
|
||||
throws TransactionException;
|
||||
TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Commit the given transaction, with regard to its status. If the transaction
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
package org.springframework.transaction;
|
||||
|
||||
/**
|
||||
* Representation of an ongoing reactive transaction.
|
||||
* Representation of an ongoing {@link ReactiveTransactionManager} transaction.
|
||||
* This is currently a marker interface extending {@link TransactionExecution}
|
||||
* but may acquire further methods in a future revision.
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
|
@ -19,7 +19,8 @@ package org.springframework.transaction;
|
|||
import java.io.Flushable;
|
||||
|
||||
/**
|
||||
* Representation of the status of a transaction.
|
||||
* Representation of an ongoing {@link PlatformTransactionManager} transaction.
|
||||
* Extends the common {@link TransactionExecution} interface.
|
||||
*
|
||||
* <p>Transactional code can use this to retrieve status information,
|
||||
* and to programmatically request a rollback (instead of throwing
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2023 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.
|
||||
|
@ -23,13 +23,13 @@ import java.io.Flushable;
|
|||
* return an internal rollback-only marker, typically from another
|
||||
* transaction that has participated and marked it as rollback-only.
|
||||
*
|
||||
* <p>Autodetected by DefaultTransactionStatus, to always return a
|
||||
* current rollbackOnly flag even if not resulting from the current
|
||||
* <p>Autodetected by {@link DefaultTransactionStatus} in order to always
|
||||
* return a current rollbackOnly flag even if not resulting from the current
|
||||
* TransactionStatus.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 1.1
|
||||
* @see DefaultTransactionStatus#isRollbackOnly
|
||||
* @see DefaultTransactionStatus#isGlobalRollbackOnly()
|
||||
*/
|
||||
public interface SmartTransactionObject extends Flushable {
|
||||
|
||||
|
|
Loading…
Reference in New Issue