You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2021/07/31 12:20:20 UTC
[isis] branch master updated: ISIS-2794: fixes InteractionService
to request a tx rollback in case the given callable or runnable throws
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new 581cadb ISIS-2794: fixes InteractionService to request a tx rollback in case the given callable or runnable throws
581cadb is described below
commit 581cadbe26e3abf12e27440739d7f3b625bf41bd
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sat Jul 31 14:20:06 2021 +0200
ISIS-2794: fixes InteractionService to request a tx rollback in case the
given callable or runnable throws
---
.../services/iactnlayer/InteractionService.java | 10 +--
.../isis/applib/services/xactn/TransactionId.java | 1 -
.../services/xactn/TransactionalProcessor.java | 12 ++--
...teractionAwareTransactionalBoundaryHandler.java | 77 +++++++++++++---------
.../session/InteractionServiceDefault.java | 45 +++++++++----
.../transaction/TransactionServiceSpring.java | 15 +++--
.../publishing/PropertyPublishingTestAbstract.java | 2 +
.../publishing/PublishingTestAbstract.java | 5 ++
...xceptionTranslationTest_usingTransactional.java | 3 +-
...ctionRollbackTest_usingInteractionService.java} | 27 ++++----
...actionRollbackTest_usingTransactionService.java | 9 +--
...TransactionRollbackTest_usingTransactional.java | 7 +-
.../publishing/PublishingTestFactoryAbstract.java | 3 +-
13 files changed, 132 insertions(+), 84 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/iactnlayer/InteractionService.java b/api/applib/src/main/java/org/apache/isis/applib/services/iactnlayer/InteractionService.java
index 7ede49d..95a4b8b 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/iactnlayer/InteractionService.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/iactnlayer/InteractionService.java
@@ -134,8 +134,9 @@ public interface InteractionService extends InteractionLayerTracker {
}
/**
- * Variant of {@link #run(InteractionContext, ThrowingRunnable)} that wraps the return value
- * with a {@link Result}, also catching any exception, that might have occurred.
+ * Variant of {@link #run(InteractionContext, ThrowingRunnable)} that returns
+ * a {@link Result} of {@code Result<Void>},
+ * also catching any exception, that might have occurred.
*/
default Result<Void> runAndCatch(
final @NonNull InteractionContext interactionContext,
@@ -153,8 +154,9 @@ public interface InteractionService extends InteractionLayerTracker {
}
/**
- * Variant of {@link #runAnonymous(ThrowingRunnable)} that wraps the return value
- * with a {@link Result}, also catching any exception, that might have occurred.
+ * Variant of {@link #runAnonymous(ThrowingRunnable)} that returns
+ * a {@link Result} of {@code Result<Void>},
+ * also catching any exception, that might have occurred.
*/
default Result<Void> runAnonymousAndCatch(
final @NonNull ThrowingRunnable runnable) {
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionId.java b/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionId.java
index b28e128..3ea93fd 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionId.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionId.java
@@ -20,7 +20,6 @@ package org.apache.isis.applib.services.xactn;
import java.util.UUID;
-import org.apache.isis.applib.mixins.system.HasInteractionId;
import org.apache.isis.applib.mixins.system.HasTransactionId;
import lombok.Value;
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionalProcessor.java b/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionalProcessor.java
index 96de969..46f436a 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionalProcessor.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionalProcessor.java
@@ -24,8 +24,8 @@ import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.support.DefaultTransactionDefinition;
-import org.apache.isis.commons.functional.Result;
import org.apache.isis.applib.services.iactnlayer.ThrowingRunnable;
+import org.apache.isis.commons.functional.Result;
import lombok.val;
@@ -52,7 +52,7 @@ public interface TransactionalProcessor {
* Runs given {@code runnable} with a transactional boundary, where the detailed transactional behavior
* is governed by given {@link TransactionDefinition} {@code def}.
*/
- default Result<Void> runTransactional(TransactionDefinition def, ThrowingRunnable runnable) {
+ default Result<Void> runTransactional(final TransactionDefinition def, final ThrowingRunnable runnable) {
return callTransactional(def, ThrowingRunnable.toCallable(runnable));
}
@@ -65,7 +65,7 @@ public interface TransactionalProcessor {
* More fine grained control is given via {@link #callTransactional(TransactionDefinition, Callable)}
* @return {@link Result} of calling given {@code callable}
*/
- default <T> Result<T> callTransactional(Propagation propagation, Callable<T> callable) {
+ default <T> Result<T> callTransactional(final Propagation propagation, final Callable<T> callable) {
val def = new DefaultTransactionDefinition();
def.setPropagationBehavior(propagation.value());
return callTransactional(def, callable);
@@ -78,7 +78,7 @@ public interface TransactionalProcessor {
* More fine grained control is given via
* {@link #runTransactional(TransactionDefinition, ThrowingRunnable)}
*/
- default Result<Void> runTransactional(Propagation propagation, ThrowingRunnable runnable) {
+ default Result<Void> runTransactional(final Propagation propagation, final ThrowingRunnable runnable) {
return callTransactional(propagation, ThrowingRunnable.toCallable(runnable));
}
@@ -94,7 +94,7 @@ public interface TransactionalProcessor {
* @param callable
* @return {@link Result} of calling given {@code callable}
*/
- default <T> Result<T> callWithinCurrentTransactionElseCreateNew(Callable<T> callable) {
+ default <T> Result<T> callWithinCurrentTransactionElseCreateNew(final Callable<T> callable) {
val def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
return callTransactional(def, callable);
@@ -106,7 +106,7 @@ public interface TransactionalProcessor {
*
* @param runnable
*/
- default Result<Void> runWithinCurrentTransactionElseCreateNew(ThrowingRunnable runnable) {
+ default Result<Void> runWithinCurrentTransactionElseCreateNew(final ThrowingRunnable runnable) {
return callWithinCurrentTransactionElseCreateNew(ThrowingRunnable.toCallable(runnable));
}
diff --git a/core/interaction/src/main/java/org/apache/isis/core/interaction/integration/InteractionAwareTransactionalBoundaryHandler.java b/core/interaction/src/main/java/org/apache/isis/core/interaction/integration/InteractionAwareTransactionalBoundaryHandler.java
index d8c8056..11cd353 100644
--- a/core/interaction/src/main/java/org/apache/isis/core/interaction/integration/InteractionAwareTransactionalBoundaryHandler.java
+++ b/core/interaction/src/main/java/org/apache/isis/core/interaction/integration/InteractionAwareTransactionalBoundaryHandler.java
@@ -30,6 +30,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
+import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionTemplate;
import org.apache.isis.applib.annotation.PriorityPrecedence;
@@ -40,6 +41,7 @@ import org.apache.isis.commons.internal.debug._Probe;
import org.apache.isis.core.interaction.session.IsisInteraction;
import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
import lombok.Value;
import lombok.val;
import lombok.extern.log4j.Log4j2;
@@ -54,7 +56,7 @@ public class InteractionAwareTransactionalBoundaryHandler {
private final Can<PlatformTransactionManager> txManagers;
@Inject
- public InteractionAwareTransactionalBoundaryHandler(List<PlatformTransactionManager> txManagers) {
+ public InteractionAwareTransactionalBoundaryHandler(final List<PlatformTransactionManager> txManagers) {
this.txManagers = Can.ofCollection(txManagers);
}
@@ -71,7 +73,7 @@ public class InteractionAwareTransactionalBoundaryHandler {
}
val onCloseTasks = _Lists.<CloseTask>newArrayList(txManagers.size());
- interaction.putAttribute(Handle.class, new Handle(onCloseTasks));
+ interaction.putAttribute(OnCloseHandle.class, new OnCloseHandle(onCloseTasks));
txManagers.forEach(txManager->newTransactionOrParticipateInExisting(txManager, onCloseTasks::add));
@@ -89,32 +91,21 @@ public class InteractionAwareTransactionalBoundaryHandler {
return; // nothing to do
}
- val onCloseTasks = Optional.ofNullable(interaction.getAttribute(Handle.class))
- .map(Handle::getOnCloseTasks);
+ Optional.ofNullable(interaction.getAttribute(OnCloseHandle.class))
+ .ifPresent(OnCloseHandle::runOnCloseTasks);
- onCloseTasks
- .ifPresent(tasks->tasks.forEach(onCloseTask->{
-
- try {
- onCloseTask.getRunnable().run();
- } catch(final Throwable ex) {
- // ignore
- log.error(
- "failed to close transactional boundary using transaction-manager {}; "
- + "continuing to avoid memory leakage",
- onCloseTask.getOnErrorInfo(),
- ex);
- }
-
- }));
+ }
+ public void requestRollback(final @NonNull IsisInteraction interaction) {
+ Optional.ofNullable(interaction.getAttribute(OnCloseHandle.class))
+ .ifPresent(OnCloseHandle::requestRollback);
}
// -- HELPER
private void newTransactionOrParticipateInExisting(
final PlatformTransactionManager txManager,
- final Consumer<CloseTask> onCloseTaskCallback) {
+ final Consumer<CloseTask> onNewCloseTask) {
val txTemplate = new TransactionTemplate(txManager);
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
@@ -129,28 +120,52 @@ public class InteractionAwareTransactionalBoundaryHandler {
// we have created a new transaction, so need to provide a CloseTask
- onCloseTaskCallback.accept(new CloseTask(
- txManager.getClass().getName(), // info to be used for display in case of errors
- ()->{
+ onNewCloseTask.accept(
+ new CloseTask(
+ txStatus,
+ txManager.getClass().getName(), // info to be used for display in case of errors
+ ()->{
- if(txStatus.isRollbackOnly()) {
- txManager.rollback(txStatus);
- } else {
- txManager.commit(txStatus);
- }
+ if(txStatus.isRollbackOnly()) {
+ txManager.rollback(txStatus);
+ } else {
+ txManager.commit(txStatus);
+ }
- }));
+ }));
}
@Value
private static class CloseTask {
+ private final @NonNull TransactionStatus txStatus;
private final @NonNull String onErrorInfo;
private final @NonNull ThrowingRunnable runnable;
}
- @Value
- private static class Handle {
+ @RequiredArgsConstructor
+ private static class OnCloseHandle {
private final @NonNull List<CloseTask> onCloseTasks;
+ void requestRollback() {
+ onCloseTasks.forEach(onCloseTask->{
+ onCloseTask.txStatus.setRollbackOnly();
+ });
+ }
+ void runOnCloseTasks() {
+ onCloseTasks.forEach(onCloseTask->{
+
+ try {
+ onCloseTask.getRunnable().run();
+ } catch(final Throwable ex) {
+ // ignore
+ log.error(
+ "failed to close transactional boundary using transaction-manager {}; "
+ + "continuing to avoid memory leakage",
+ onCloseTask.getOnErrorInfo(),
+ ex);
+ }
+
+ });
+ }
}
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionServiceDefault.java
index 54ce7ae..65ebdf8 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/session/InteractionServiceDefault.java
@@ -246,10 +246,8 @@ implements
final int stackSizeWhenEntering = interactionLayerStack.get().size();
openInteraction(interactionContext);
-
try {
- serviceInjector.injectServicesInto(callable);
- return callable.call();
+ return callInternal(callable);
} finally {
closeInteractionLayerStackDownToStackSize(stackSizeWhenEntering);
}
@@ -263,14 +261,11 @@ implements
final int stackSizeWhenEntering = interactionLayerStack.get().size();
openInteraction(interactionContext);
-
try {
- serviceInjector.injectServicesInto(runnable);
- runnable.run();
+ runInternal(runnable);
} finally {
closeInteractionLayerStackDownToStackSize(stackSizeWhenEntering);
}
-
}
// -- ANONYMOUS EXECUTION
@@ -279,8 +274,7 @@ implements
@SneakyThrows
public <R> R callAnonymous(@NonNull final Callable<R> callable) {
if(isInInteraction()) {
- serviceInjector.injectServicesInto(callable);
- return callable.call(); // reuse existing session
+ return callInternal(callable); // participate in existing session
}
return call(InteractionContextFactory.anonymous(), callable);
}
@@ -291,10 +285,9 @@ implements
*/
@Override
@SneakyThrows
- public void runAnonymous(@NonNull final ThrowingRunnable runnable) {
+ public void runAnonymous(final @NonNull ThrowingRunnable runnable) {
if(isInInteraction()) {
- serviceInjector.injectServicesInto(runnable);
- runnable.run(); // reuse existing session
+ runInternal(runnable); // participate in existing session
return;
}
run(InteractionContextFactory.anonymous(), runnable);
@@ -311,6 +304,34 @@ implements
// -- HELPER
+ @SneakyThrows
+ private <R> R callInternal(final @NonNull Callable<R> callable) {
+ serviceInjector.injectServicesInto(callable);
+ try {
+ return callable.call();
+ } catch (Exception e) {
+ requestRollback();
+ throw e;
+ }
+ }
+
+ @SneakyThrows
+ private void runInternal(final @NonNull ThrowingRunnable runnable) {
+ serviceInjector.injectServicesInto(runnable);
+ try {
+ runnable.run();
+ } catch (Exception e) {
+ requestRollback();
+ throw e;
+ }
+ }
+
+ private void requestRollback() {
+ val stack = interactionLayerStack.get();
+ val interaction = _Casts.<IsisInteraction>uncheckedCast(stack.get(0).getInteraction());
+ txBoundaryHandler.requestRollback(interaction);
+ }
+
private boolean isAtTopLevel() {
return interactionLayerStack.get().size()==1;
}
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/transaction/TransactionServiceSpring.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/transaction/TransactionServiceSpring.java
index 904c984..11b14a4 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/transaction/TransactionServiceSpring.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/transaction/TransactionServiceSpring.java
@@ -97,15 +97,17 @@ implements
@Override
public <T> Result<T> callTransactional(final TransactionDefinition def, final Callable<T> callable) {
- val txManager = transactionManagerForElseFail(def);
+ val txManager = transactionManagerForElseFail(def); // always throws if configuration is wrong
- val tx = txManager.getTransaction(def);
-
- val result = Result.of(callable)
- .mapFailure(ex->translateExceptionIfPossible(ex, txManager));
+ Result<T> result = null;
try {
+ val tx = txManager.getTransaction(def);
+
+ result = Result.of(callable)
+ .mapFailure(ex->translateExceptionIfPossible(ex, txManager));
+
if(result.isFailure()) {
txManager.rollback(tx);
} else {
@@ -114,7 +116,8 @@ implements
} catch (Exception ex) {
- return result.isFailure()
+ return result!=null
+ && result.isFailure()
// return the original failure cause (originating from calling the callable)
// (so we don't shadow the original failure)
diff --git a/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/PropertyPublishingTestAbstract.java b/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/PropertyPublishingTestAbstract.java
index f5d1f08..65d5a7c 100644
--- a/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/PropertyPublishingTestAbstract.java
+++ b/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/PropertyPublishingTestAbstract.java
@@ -64,6 +64,8 @@ extends PublishingTestAbstract {
switch(changeScenario) {
case ENTITY_CREATION:
return; // factory-service does not trigger property publishing
+ case ENTITY_LOADING:
+ return; // not subject of change tests
case ENTITY_PERSISTING:
assertContainsPropertyChangeEntries(Can.of(
formatPersistenceStandardSpecificCapitalize("%s Book/name: '[NEW]' -> 'Sample Book'")));
diff --git a/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/PublishingTestAbstract.java b/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/PublishingTestAbstract.java
index 454607a..0489435 100644
--- a/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/PublishingTestAbstract.java
+++ b/regressiontests/incubating/src/test/java/org/apache/isis/testdomain/publishing/PublishingTestAbstract.java
@@ -24,6 +24,11 @@ implements HasPersistenceStandard {
return generateTests(ChangeScenario.ENTITY_CREATION);
}
+ @TestFactory @DisplayName("Entity Persisting")
+ final List<DynamicTest> generateTestsForPersisting() {
+ return generateTests(ChangeScenario.ENTITY_PERSISTING);
+ }
+
@TestFactory @DisplayName("Entity Loading")
final List<DynamicTest> generateTestsForLoading() {
return generateTests(ChangeScenario.ENTITY_LOADING);
diff --git a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/JpaExceptionTranslationTest_usingTransactional.java b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/JpaExceptionTranslationTest_usingTransactional.java
index f9dece0..d4836ec 100644
--- a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/JpaExceptionTranslationTest_usingTransactional.java
+++ b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/persistence/jpa/JpaExceptionTranslationTest_usingTransactional.java
@@ -31,7 +31,6 @@ import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.DataIntegrityViolationException;
-import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.TestPropertySource;
@@ -74,7 +73,7 @@ class JpaExceptionTranslationTest_usingTransactional
@Inject private RepositoryService repositoryService;
@Inject private InteractionService interactionService;
@Inject private Provider<JpaInventoryDao> inventoryDao;
- @Inject private JpaTransactionManager txManager;
+ //@Inject private JpaTransactionManager txManager;
@BeforeAll
static void beforeAll() throws SQLException {
diff --git a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingTransactionService.java b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingInteractionService.java
similarity index 89%
copy from regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingTransactionService.java
copy to regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingInteractionService.java
index f63658a..8746594 100644
--- a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingTransactionService.java
+++ b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingInteractionService.java
@@ -35,11 +35,11 @@ import org.springframework.test.context.TestPropertySource;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.apache.isis.applib.services.iactnlayer.InteractionService;
import org.apache.isis.applib.services.repository.RepositoryService;
import org.apache.isis.applib.services.xactn.TransactionService;
import org.apache.isis.commons.internal.base._Refs;
import org.apache.isis.commons.internal.base._Refs.ObjectReference;
-import org.apache.isis.commons.internal.debug._Probe;
import org.apache.isis.core.config.presets.IsisPresets;
import org.apache.isis.core.transaction.events.TransactionAfterCompletionEvent;
import org.apache.isis.core.transaction.events.TransactionBeforeCompletionEvent;
@@ -55,7 +55,7 @@ import lombok.val;
@SpringBootTest(
classes = {
Configuration_usingJpa.class,
- JpaTransactionRollbackTest_usingTransactionService.CommitListener.class
+ JpaTransactionRollbackTest_usingInteractionService.CommitListener.class
},
properties = {
// "logging.level.org.springframework.test.context.transaction.*=DEBUG",
@@ -64,12 +64,13 @@ import lombok.val;
@TestPropertySource(IsisPresets.UseLog4j2Test)
@ExtendWith({IsisInteractionHandler.class})
@DirtiesContext
-class JpaTransactionRollbackTest_usingTransactionService
+class JpaTransactionRollbackTest_usingInteractionService
//extends IsisIntegrationTestAbstract
{
@Inject private FixtureScripts fixtureScripts;
@Inject private TransactionService transactionService;
+ @Inject private InteractionService interactionService;
@Inject private RepositoryService repository;
@Inject private CommitListener commitListener;
@@ -96,7 +97,7 @@ class JpaTransactionRollbackTest_usingTransactionService
commitListener.bind(transactionAfterCompletionEvent::set);
- transactionService.runWithinCurrentTransactionElseCreateNew(()->{
+ interactionService.runAnonymous(()->{
fixtureScripts.runPersona(JpaTestDomainPersona.InventoryWith1Book);
});
@@ -126,7 +127,7 @@ class JpaTransactionRollbackTest_usingTransactionService
commitListener.bind(transactionAfterCompletionEvent::set);
- val result = transactionService.runWithinCurrentTransactionElseCreateNew(()->{
+ val result = interactionService.runAnonymousAndCatch(()->{
fixtureScripts.runPersona(JpaTestDomainPersona.InventoryWith1Book);
@@ -157,33 +158,35 @@ class JpaTransactionRollbackTest_usingTransactionService
assertEquals(0, repository.allInstances(JpaBook.class).size());
});
- _Probe.errOut("before outer tx");
+ //_Probe.errOut("before outer tx");
commitListener.bind(transactionAfterCompletionEvent::set);
- val result = transactionService.runWithinCurrentTransactionElseCreateNew(()->{
+ val result = interactionService.runAnonymousAndCatch(()->{
//_Probe.errOut("before tx that should trigger a rollback");
- transactionService.runWithinCurrentTransactionElseCreateNew(()->{
+ val innerResult = transactionService.runWithinCurrentTransactionElseCreateNew(()->{
fixtureScripts.runPersona(JpaTestDomainPersona.InventoryWith1Book);
throw new RuntimeException("Test: force current tx to rollback");
});
+ assertTrue(innerResult.isFailure());
+
//_Probe.errOut("after tx that should have triggered a rollback");
});
- _Probe.errOut("after outer tx");
+ //_Probe.errOut("after outer tx");
- assertTrue(result.isFailure());
+ // interactionService detects whether a rollback was requested and does not throw in such a case
+ assertTrue(result.isSuccess());
val actualEvent = transactionAfterCompletionEvent.getValueElseDefault(null);
assertTrue(
- actualEvent == TransactionAfterCompletionEvent.ROLLED_BACK
- || actualEvent == TransactionAfterCompletionEvent.UNKNOWN);
+ actualEvent == TransactionAfterCompletionEvent.ROLLED_BACK);
transactionService.runWithinCurrentTransactionElseCreateNew(()->{
diff --git a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingTransactionService.java b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingTransactionService.java
index f63658a..27031b4 100644
--- a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingTransactionService.java
+++ b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingTransactionService.java
@@ -39,7 +39,6 @@ import org.apache.isis.applib.services.repository.RepositoryService;
import org.apache.isis.applib.services.xactn.TransactionService;
import org.apache.isis.commons.internal.base._Refs;
import org.apache.isis.commons.internal.base._Refs.ObjectReference;
-import org.apache.isis.commons.internal.debug._Probe;
import org.apache.isis.core.config.presets.IsisPresets;
import org.apache.isis.core.transaction.events.TransactionAfterCompletionEvent;
import org.apache.isis.core.transaction.events.TransactionBeforeCompletionEvent;
@@ -157,7 +156,7 @@ class JpaTransactionRollbackTest_usingTransactionService
assertEquals(0, repository.allInstances(JpaBook.class).size());
});
- _Probe.errOut("before outer tx");
+ //_Probe.errOut("before outer tx");
commitListener.bind(transactionAfterCompletionEvent::set);
@@ -165,7 +164,7 @@ class JpaTransactionRollbackTest_usingTransactionService
//_Probe.errOut("before tx that should trigger a rollback");
- transactionService.runWithinCurrentTransactionElseCreateNew(()->{
+ val innerResult = transactionService.runWithinCurrentTransactionElseCreateNew(()->{
fixtureScripts.runPersona(JpaTestDomainPersona.InventoryWith1Book);
@@ -174,9 +173,11 @@ class JpaTransactionRollbackTest_usingTransactionService
//_Probe.errOut("after tx that should have triggered a rollback");
+ assertTrue(innerResult.isFailure());
+
});
- _Probe.errOut("after outer tx");
+ //_Probe.errOut("after outer tx");
assertTrue(result.isFailure());
diff --git a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingTransactional.java b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingTransactional.java
index b8ccbf0..29f4e24 100644
--- a/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingTransactional.java
+++ b/regressiontests/stable-persistence-jpa/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingTransactional.java
@@ -33,7 +33,6 @@ import org.springframework.transaction.annotation.Transactional;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.apache.isis.applib.services.repository.RepositoryService;
-import org.apache.isis.commons.internal.debug._Probe;
import org.apache.isis.core.config.presets.IsisPresets;
import org.apache.isis.testdomain.conf.Configuration_usingJpa;
import org.apache.isis.testdomain.jpa.JpaTestDomainPersona;
@@ -51,9 +50,9 @@ import org.apache.isis.testing.integtestsupport.applib.IsisIntegrationTestAbstra
Configuration_usingJpa.class,
},
properties = {
- "logging.level.org.apache.isis.core.runtimeservices.session.InteractionFactoryDefault=DEBUG",
- "logging.level.org.apache.isis.persistence.*=DEBUG",
- "logging.level.org.springframework.test.context.transaction.*=DEBUG"
+// "logging.level.org.apache.isis.core.runtimeservices.session.InteractionFactoryDefault=DEBUG",
+// "logging.level.org.apache.isis.persistence.*=DEBUG",
+// "logging.level.org.springframework.test.context.transaction.*=DEBUG"
})
@Transactional
@TestPropertySource(IsisPresets.UseLog4j2Test)
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryAbstract.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryAbstract.java
index 5e58d80..a72a428 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryAbstract.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/publishing/PublishingTestFactoryAbstract.java
@@ -358,13 +358,12 @@ public abstract class PublishingTestFactoryAbstract {
// return result;
// });
- val result = getInteractionService().callAnonymous(()->{
+ val result = getInteractionService().runAnonymousAndCatch(()->{
val currentInteraction = getInteractionService().currentInteraction();
xrayEnterInteraction(currentInteraction);
try {
testRunner.run(testContext); // is allowed to throw
- return Result.success(true);
} finally {
xrayExitInteraction();
}