Skip to content

Commit 8a67aca

Browse files
committed
Option 2: drop the unwrapping, propagate RuntimeException
1 parent ca58073 commit 8a67aca

File tree

6 files changed

+36
-54
lines changed

6 files changed

+36
-54
lines changed

spring-r2dbc/src/test/java/org/springframework/r2dbc/connection/R2dbcTransactionManagerUnitTests.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,9 @@ void testCommitFails() {
256256
.doOnNext(connection -> connection.createStatement("foo")).then()
257257
.as(operator::transactional)
258258
.as(StepVerifier::create)
259-
.verifyError(BadSqlGrammarException.class);
259+
.verifyErrorSatisfies(ex -> assertThat(ex)
260+
.isExactlyInstanceOf(RuntimeException.class)
261+
.hasCauseInstanceOf(BadSqlGrammarException.class));
260262

261263
verify(connectionMock).isAutoCommit();
262264
verify(connectionMock).beginTransaction();
@@ -309,7 +311,9 @@ void testRollbackFails() {
309311
return ConnectionFactoryUtils.getConnection(connectionFactoryMock)
310312
.doOnNext(connection -> connection.createStatement("foo")).then();
311313
}).as(StepVerifier::create)
312-
.verifyError(BadSqlGrammarException.class);
314+
.verifyErrorSatisfies(ex -> assertThat(ex)
315+
.isExactlyInstanceOf(RuntimeException.class)
316+
.hasCauseInstanceOf(BadSqlGrammarException.class));
313317

314318
verify(connectionMock).isAutoCommit();
315319
verify(connectionMock).beginTransaction();

spring-tx/src/main/java/org/springframework/transaction/interceptor/TransactionAspectSupport.java

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -921,8 +921,7 @@ public Object invokeWithinTransaction(Method method, @Nullable Class<?> targetCl
921921
},
922922
this::commitTransactionAfterReturning,
923923
this::completeTransactionAfterThrowing,
924-
this::rollbackTransactionOnCancel)
925-
.onErrorMap(this::unwrapIfResourceCleanupFailure))
924+
this::rollbackTransactionOnCancel))
926925
.contextWrite(TransactionContextManager.getOrCreateContext())
927926
.contextWrite(TransactionContextManager.getOrCreateContextHolder());
928927
}
@@ -941,8 +940,7 @@ public Object invokeWithinTransaction(Method method, @Nullable Class<?> targetCl
941940
},
942941
this::commitTransactionAfterReturning,
943942
this::completeTransactionAfterThrowing,
944-
this::rollbackTransactionOnCancel)
945-
.onErrorMap(this::unwrapIfResourceCleanupFailure))
943+
this::rollbackTransactionOnCancel))
946944
.contextWrite(TransactionContextManager.getOrCreateContext())
947945
.contextWrite(TransactionContextManager.getOrCreateContextHolder()));
948946
}
@@ -1024,9 +1022,6 @@ private Mono<Void> completeTransactionAfterThrowing(@Nullable ReactiveTransactio
10241022
if (ex2 instanceof TransactionSystemException) {
10251023
((TransactionSystemException) ex2).initApplicationException(ex);
10261024
}
1027-
else {
1028-
ex2.addSuppressed(ex);
1029-
}
10301025
return ex2;
10311026
}
10321027
);
@@ -1039,30 +1034,13 @@ private Mono<Void> completeTransactionAfterThrowing(@Nullable ReactiveTransactio
10391034
if (ex2 instanceof TransactionSystemException) {
10401035
((TransactionSystemException) ex2).initApplicationException(ex);
10411036
}
1042-
else {
1043-
ex2.addSuppressed(ex);
1044-
}
10451037
return ex2;
10461038
}
10471039
);
10481040
}
10491041
}
10501042
return Mono.empty();
10511043
}
1052-
1053-
/**
1054-
* Unwrap the cause of a throwable, if produced by a failure
1055-
* during the async resource cleanup in {@link Flux#usingWhen}.
1056-
* @param ex the throwable to try to unwrap
1057-
*/
1058-
private Throwable unwrapIfResourceCleanupFailure(Throwable ex) {
1059-
if (ex instanceof RuntimeException &&
1060-
ex.getCause() != null &&
1061-
ex.getMessage().startsWith("Async resource cleanup failed")) {
1062-
return ex.getCause();
1063-
}
1064-
return ex;
1065-
}
10661044
}
10671045

10681046

spring-tx/src/main/java/org/springframework/transaction/reactive/TransactionalOperatorImpl.java

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,7 @@ public <T> Flux<T> execute(TransactionCallback<T> action) throws TransactionExce
7979
action::doInTransaction,
8080
this.transactionManager::commit,
8181
this::rollbackOnException,
82-
this.transactionManager::rollback)
83-
.onErrorMap(this::unwrapIfResourceCleanupFailure))
82+
this.transactionManager::rollback))
8483
.contextWrite(TransactionContextManager.getOrCreateContext())
8584
.contextWrite(TransactionContextManager.getOrCreateContextHolder());
8685
}
@@ -98,28 +97,11 @@ private Mono<Void> rollbackOnException(ReactiveTransaction status, Throwable ex)
9897
if (ex2 instanceof TransactionSystemException) {
9998
((TransactionSystemException) ex2).initApplicationException(ex);
10099
}
101-
else {
102-
ex2.addSuppressed(ex);
103-
}
104100
return ex2;
105101
}
106102
);
107103
}
108104

109-
/**
110-
* Unwrap the cause of a throwable, if produced by a failure
111-
* during the async resource cleanup in {@link Flux#usingWhen}.
112-
* @param ex the throwable to try to unwrap
113-
*/
114-
private Throwable unwrapIfResourceCleanupFailure(Throwable ex) {
115-
if (ex instanceof RuntimeException &&
116-
ex.getCause() != null &&
117-
ex.getMessage().startsWith("Async resource cleanup failed")) {
118-
return ex.getCause();
119-
}
120-
return ex;
121-
}
122-
123105

124106
@Override
125107
public boolean equals(@Nullable Object other) {

spring-tx/src/test/java/org/springframework/transaction/interceptor/AbstractReactiveTransactionAspectTests.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,9 @@ public boolean rollbackOn(Throwable t) {
256256
.as(StepVerifier::create)
257257
.expectErrorSatisfies(actual -> {
258258
if (rollbackException) {
259-
assertThat(actual).isEqualTo(tex);
259+
assertThat(actual)
260+
.isExactlyInstanceOf(RuntimeException.class)
261+
.hasCause(tex);
260262
}
261263
else {
262264
assertThat(actual).isEqualTo(ex);
@@ -335,7 +337,9 @@ public void cannotCommitTransaction() throws Exception {
335337

336338
Mono.from(itb.setName(name))
337339
.as(StepVerifier::create)
338-
.verifyErrorSatisfies(actual -> assertThat(actual).isEqualTo(ex));
340+
.verifyErrorSatisfies(actual -> assertThat(actual)
341+
.isExactlyInstanceOf(RuntimeException.class)
342+
.hasCause(ex));
339343

340344
// Should have invoked target and changed name
341345

spring-tx/src/test/java/org/springframework/transaction/reactive/TransactionalOperatorTests.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,9 @@ public void commitFailureWithMono() {
119119
TransactionalOperator operator = TransactionalOperator.create(tm, new DefaultTransactionDefinition());
120120
Mono.just(true).as(operator::transactional)
121121
.as(StepVerifier::create)
122-
.verifyError(IOException.class);
122+
.verifyErrorSatisfies(ex -> assertThat(ex)
123+
.isExactlyInstanceOf(RuntimeException.class)
124+
.hasCauseInstanceOf(IOException.class));
123125
assertThat(commit.subscribeCount()).isEqualTo(1);
124126
rollback.assertWasNotSubscribed();
125127
}
@@ -138,7 +140,8 @@ public void rollbackFailureWithMono() {
138140
Mono.error(actionFailure).as(operator::transactional)
139141
.as(StepVerifier::create)
140142
.verifyErrorSatisfies(ex -> assertThat(ex)
141-
.isInstanceOf(IOException.class)
143+
.isExactlyInstanceOf(RuntimeException.class)
144+
.hasCauseInstanceOf(IOException.class)
142145
.hasSuppressedException(actionFailure));
143146
commit.assertWasNotSubscribed();
144147
assertThat(rollback.subscribeCount()).isEqualTo(1);
@@ -178,7 +181,9 @@ public void commitFailureWithFlux() {
178181
Flux.just(1, 2, 3, 4).as(operator::transactional)
179182
.as(StepVerifier::create)
180183
.expectNextCount(4)
181-
.verifyError(IOException.class);
184+
.verifyErrorSatisfies(ex -> assertThat(ex)
185+
.isExactlyInstanceOf(RuntimeException.class)
186+
.hasCauseInstanceOf(IOException.class));
182187
assertThat(commit.subscribeCount()).isEqualTo(1);
183188
rollback.assertWasNotSubscribed();
184189
}
@@ -198,7 +203,8 @@ public void rollbackFailureWithFlux() {
198203
.as(StepVerifier::create)
199204
.expectNextCount(3)
200205
.verifyErrorSatisfies(ex -> assertThat(ex)
201-
.isInstanceOf(IOException.class)
206+
.isExactlyInstanceOf(RuntimeException.class)
207+
.hasCauseInstanceOf(IOException.class)
202208
.hasSuppressedException(actionFailure));
203209
commit.assertWasNotSubscribed();
204210
assertThat(rollback.subscribeCount()).isEqualTo(1);

spring-tx/src/test/kotlin/org/springframework/transaction/interceptor/AbstractCoroutinesTransactionAspectTests.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,11 @@ abstract class AbstractCoroutinesTransactionAspectTests {
218218
}
219219
catch (actual: Exception) {
220220
if (rollbackException) {
221-
Assertions.assertThat(actual).hasMessage(tex.message).isInstanceOf(tex::class.java)
221+
Assertions.assertThat(actual)
222+
.isExactlyInstanceOf(RuntimeException::class.java)
223+
.cause
224+
.isExactlyInstanceOf(RuntimeException::class.java)
225+
.hasCause(tex)
222226
} else {
223227
Assertions.assertThat(actual).hasMessage(ex.message).isInstanceOf(ex::class.java)
224228
}
@@ -291,7 +295,11 @@ abstract class AbstractCoroutinesTransactionAspectTests {
291295
itb.setName(name)
292296
}
293297
catch (actual: Exception) {
294-
Assertions.assertThat(actual).isEqualTo(ex)
298+
Assertions.assertThat(actual)
299+
.isExactlyInstanceOf(RuntimeException::class.java)
300+
.cause
301+
.isExactlyInstanceOf(RuntimeException::class.java)
302+
.hasCause(ex)
295303
}
296304
// Should have invoked target and changed name
297305
Assertions.assertThat(itb.getName()).isEqualTo(name)
@@ -352,4 +360,4 @@ abstract class AbstractCoroutinesTransactionAspectTests {
352360
}
353361
}
354362
}
355-
}
363+
}

0 commit comments

Comments
 (0)