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 2020/12/30 19:07:54 UTC
[isis] branch 2033-Spring_Data_Integration updated: ISIS-2033:
remove Isis homebrew tx integration for JDO
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch 2033-Spring_Data_Integration
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/2033-Spring_Data_Integration by this push:
new e902d3c ISIS-2033: remove Isis homebrew tx integration for JDO
e902d3c is described below
commit e902d3c1b1f48b036ee99dbd69661ec78e6e906a
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Dec 30 20:07:42 2020 +0100
ISIS-2033: remove Isis homebrew tx integration for JDO
also remove Transaction from Applib
---
.../isis/applib/services/xactn/Transaction.java | 46 ---
.../events/TransactionAfterBeginEvent.java | 4 +-
.../events/TransactionAfterCommitEvent.java | 4 +-
.../events/TransactionAfterRollbackEvent.java | 4 +-
.../events/TransactionBeforeBeginEvent.java | 4 +-
.../events/TransactionBeforeCommitEvent.java | 4 +-
.../events/TransactionBeforeRollbackEvent.java | 4 +-
.../events/TransactionEventAbstract.java | 8 +-
.../integration/IsisTransactionAspectSupport.java | 63 ----
.../integration/IsisTransactionObject.java | 108 -------
...IsisPlatformTransactionManagerForJdoNoMore.java | 152 ---------
.../transaction/TxManagerInternalFactory.java | 46 ---
.../jdo/integration/transaction/_Tx.java | 342 ---------------------
.../jdo/integration/transaction/_TxProcessor.java | 325 --------------------
.../sse/ui/wkt/services/SseServiceDefault.java | 13 +-
15 files changed, 21 insertions(+), 1106 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/xactn/Transaction.java b/api/applib/src/main/java/org/apache/isis/applib/services/xactn/Transaction.java
deleted file mode 100644
index fa36288..0000000
--- a/api/applib/src/main/java/org/apache/isis/applib/services/xactn/Transaction.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.isis.applib.services.xactn;
-
-/**
- * Representation of the current transaction, which conceptually wraps the underlying transaction context's transaction.
- * @since 1.x {@index}
- */
-public interface Transaction {
-
- TransactionId getId();
-
- /**
- * Flush all changes to the object store.
- *
- * <p>
- * Occasionally useful to ensure that newly persisted domain objects
- * are flushed to the database prior to a subsequent repository query.
- * </p>
- *
- * <p>
- * Equivalent to {@link TransactionService#flushTransaction()}.
- * </p>
- */
- void flush();
-
- TransactionState getTransactionState();
-
-}
diff --git a/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionAfterBeginEvent.java b/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionAfterBeginEvent.java
index 760e92c..5d57eaa 100644
--- a/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionAfterBeginEvent.java
+++ b/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionAfterBeginEvent.java
@@ -18,13 +18,13 @@
*/
package org.apache.isis.core.transaction.events;
-import org.apache.isis.core.transaction.integration.IsisTransactionObject;
+import org.springframework.transaction.TransactionStatus;
public class TransactionAfterBeginEvent extends TransactionEventAbstract {
private static final long serialVersionUID = 1L;
- public TransactionAfterBeginEvent(final IsisTransactionObject source) {
+ public TransactionAfterBeginEvent(final TransactionStatus source) {
super(source, Type.AFTER_BEGIN);
}
diff --git a/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionAfterCommitEvent.java b/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionAfterCommitEvent.java
index 01572e5..c1e5470 100644
--- a/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionAfterCommitEvent.java
+++ b/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionAfterCommitEvent.java
@@ -18,13 +18,13 @@
*/
package org.apache.isis.core.transaction.events;
-import org.apache.isis.core.transaction.integration.IsisTransactionObject;
+import org.springframework.transaction.TransactionStatus;
public class TransactionAfterCommitEvent extends TransactionEventAbstract {
private static final long serialVersionUID = 1L;
- public TransactionAfterCommitEvent(final IsisTransactionObject source) {
+ public TransactionAfterCommitEvent(final TransactionStatus source) {
super(source, Type.AFTER_COMMIT);
}
}
diff --git a/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionAfterRollbackEvent.java b/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionAfterRollbackEvent.java
index 3ee6738..9d9bba7 100644
--- a/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionAfterRollbackEvent.java
+++ b/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionAfterRollbackEvent.java
@@ -18,13 +18,13 @@
*/
package org.apache.isis.core.transaction.events;
-import org.apache.isis.core.transaction.integration.IsisTransactionObject;
+import org.springframework.transaction.TransactionStatus;
public class TransactionAfterRollbackEvent extends TransactionEventAbstract {
private static final long serialVersionUID = 1L;
- public TransactionAfterRollbackEvent(final IsisTransactionObject source) {
+ public TransactionAfterRollbackEvent(final TransactionStatus source) {
super(source, Type.AFTER_ROLLBACK);
}
}
\ No newline at end of file
diff --git a/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionBeforeBeginEvent.java b/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionBeforeBeginEvent.java
index fa1df51..817168e 100644
--- a/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionBeforeBeginEvent.java
+++ b/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionBeforeBeginEvent.java
@@ -18,13 +18,13 @@
*/
package org.apache.isis.core.transaction.events;
-import org.apache.isis.core.transaction.integration.IsisTransactionObject;
+import org.springframework.transaction.TransactionStatus;
public class TransactionBeforeBeginEvent extends TransactionEventAbstract {
private static final long serialVersionUID = 1L;
- public TransactionBeforeBeginEvent(final IsisTransactionObject source) {
+ public TransactionBeforeBeginEvent(final TransactionStatus source) {
super(source, Type.BEFORE_BEGIN);
}
diff --git a/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionBeforeCommitEvent.java b/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionBeforeCommitEvent.java
index 283b5ec..e35fad1 100644
--- a/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionBeforeCommitEvent.java
+++ b/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionBeforeCommitEvent.java
@@ -18,13 +18,13 @@
*/
package org.apache.isis.core.transaction.events;
-import org.apache.isis.core.transaction.integration.IsisTransactionObject;
+import org.springframework.transaction.TransactionStatus;
public class TransactionBeforeCommitEvent extends TransactionEventAbstract {
private static final long serialVersionUID = 1L;
- public TransactionBeforeCommitEvent(final IsisTransactionObject source) {
+ public TransactionBeforeCommitEvent(final TransactionStatus source) {
super(source, Type.BEFORE_COMMIT);
}
}
\ No newline at end of file
diff --git a/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionBeforeRollbackEvent.java b/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionBeforeRollbackEvent.java
index ca04cee..6b66ecc 100644
--- a/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionBeforeRollbackEvent.java
+++ b/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionBeforeRollbackEvent.java
@@ -18,13 +18,13 @@
*/
package org.apache.isis.core.transaction.events;
-import org.apache.isis.core.transaction.integration.IsisTransactionObject;
+import org.springframework.transaction.TransactionStatus;
public class TransactionBeforeRollbackEvent extends TransactionEventAbstract {
private static final long serialVersionUID = 1L;
- public TransactionBeforeRollbackEvent(final IsisTransactionObject source) {
+ public TransactionBeforeRollbackEvent(final TransactionStatus source) {
super(source, Type.BEFORE_ROLLBACK);
}
}
\ No newline at end of file
diff --git a/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionEventAbstract.java b/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionEventAbstract.java
index 636a896..1c54abe 100644
--- a/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionEventAbstract.java
+++ b/core/transaction/src/main/java/org/apache/isis/core/transaction/events/TransactionEventAbstract.java
@@ -20,7 +20,7 @@ package org.apache.isis.core.transaction.events;
import java.util.EventObject;
-import org.apache.isis.core.transaction.integration.IsisTransactionObject;
+import org.springframework.transaction.TransactionStatus;
import lombok.Getter;
@@ -41,16 +41,16 @@ public abstract class TransactionEventAbstract extends EventObject {
* Same as {@link #getSource()}.
*/
@Getter
- private final IsisTransactionObject isisTransactionObject;
+ private final TransactionStatus transactionStatus;
@Getter
private final Type type;
public TransactionEventAbstract(
- final IsisTransactionObject source,
+ final TransactionStatus source,
final Type type) {
super(source);
- this.isisTransactionObject = source;
+ this.transactionStatus = source;
this.type = type;
}
diff --git a/core/transaction/src/main/java/org/apache/isis/core/transaction/integration/IsisTransactionAspectSupport.java b/core/transaction/src/main/java/org/apache/isis/core/transaction/integration/IsisTransactionAspectSupport.java
deleted file mode 100644
index f520322..0000000
--- a/core/transaction/src/main/java/org/apache/isis/core/transaction/integration/IsisTransactionAspectSupport.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.isis.core.transaction.integration;
-
-import java.util.Optional;
-
-import org.apache.isis.commons.concurrent.AwaitableLatch;
-import org.apache.isis.commons.internal.context._Context;
-
-public final class IsisTransactionAspectSupport {
-
- public static void clearTransactionObject() {
- _Context.threadLocalClear(IsisTransactionObject.class);
- }
-
- public static void putTransactionObject(IsisTransactionObject txStatus) {
- // TODO: review - rather than using a thread-local, and alternative
- // might be to have IsisInteraction provide a "userData" map to allow
- // arbitrary interaction-scoped objects to be stored there...
- // ... of which IsisTransactionObject is one (the other is
- // PersistenceSession). Then, only IsisInteractionFactory needs to
- // maintain a thread-local (and if we change to some other way of
- // finding the current IsisInteraction, eg from HttpRequest, then
- // there's no impact elsewhere).
- _Context.threadLocalPut(IsisTransactionObject.class, txStatus);
- }
-
- public static Optional<IsisTransactionObject> currentTransactionObject() {
- return _Context.threadLocalGet(IsisTransactionObject.class)
- .getFirst();
- }
-
- public static boolean isTransactionInProgress() {
- return currentTransactionObject()
- .map(IsisTransactionObject::getCountDownLatch)
- .map(latch->latch.getCount()>0)
- .orElse(false);
- }
-
- public static AwaitableLatch transactionLatch() {
- return currentTransactionObject()
- .map(IsisTransactionObject::getCountDownLatch)
- .map(AwaitableLatch::of)
- .orElseGet(AwaitableLatch::unlocked);
- }
-
-}
diff --git a/core/transaction/src/main/java/org/apache/isis/core/transaction/integration/IsisTransactionObject.java b/core/transaction/src/main/java/org/apache/isis/core/transaction/integration/IsisTransactionObject.java
deleted file mode 100644
index 584c7aa..0000000
--- a/core/transaction/src/main/java/org/apache/isis/core/transaction/integration/IsisTransactionObject.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.isis.core.transaction.integration;
-
-import java.util.concurrent.CountDownLatch;
-
-import org.springframework.transaction.support.SmartTransactionObject;
-
-import org.apache.isis.applib.services.xactn.Transaction;
-import org.apache.isis.applib.services.xactn.TransactionId;
-
-import lombok.Getter;
-import lombok.Setter;
-import lombok.ToString;
-import lombok.val;
-
-@ToString
-public class IsisTransactionObject implements SmartTransactionObject {
-
- public static enum IsisInteractionScopeType {
- /** an IsisInteraction was already present when creating this txObj */
- REQUEST_SCOPED,
- /** an IsisInteraction was auto-created when creating this txObj,
- * so we need to take core of closing it; most likely in the context of testing */
- TEST_SCOPED
- }
-
- public static IsisTransactionObject of(Transaction currentTransaction, IsisInteractionScopeType isisInteractionScopeType) {
- val txObject = new IsisTransactionObject();
- txObject.setCurrentTransaction(currentTransaction);
- txObject.setIsisInteractionScopeType(isisInteractionScopeType);
- return txObject;
- }
-
- @Getter @Setter Transaction currentTransaction;
- @Getter @Setter IsisInteractionScopeType isisInteractionScopeType;
-
-
- @Override
- public boolean isRollbackOnly() {
- return currentTransaction.getTransactionState().mustAbort();
- }
-
- @Override
- public void flush() {
- if(currentTransaction!=null) {
- currentTransaction.flush();
- }
- }
-
- public TransactionId getTransactionId() {
- if(currentTransaction!=null) {
- return currentTransaction.getId();
- }
- return null;
- }
-
- // -- RESET
-
- public void clear() {
- transactionNestingLevel = 0;
- setCurrentTransaction(null);
- }
-
- // -- THREAD SYNCHRONICATION
-
- /**
- * A latch that allows threads to wait on. The latch count drops to zero once
- * this transaction completes.
- */
- @Getter private final CountDownLatch countDownLatch = new CountDownLatch(1);
-
- // -- NESTING
-
- @Getter private int transactionNestingLevel = 0;
-
- public int incTransactionNestingLevel() {
- return ++transactionNestingLevel;
- }
-
- public int decTransactionNestingLevel() {
- if(transactionNestingLevel==0) {
- return 0;
- }
- return --transactionNestingLevel;
- }
-
- public boolean isTopLevel() {
- return transactionNestingLevel == 0;
- }
-
-}
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/IsisPlatformTransactionManagerForJdoNoMore.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/IsisPlatformTransactionManagerForJdoNoMore.java
deleted file mode 100644
index 4d19bdd..0000000
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/IsisPlatformTransactionManagerForJdoNoMore.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.isis.persistence.jdo.integration.transaction;
-
-import org.springframework.transaction.TransactionDefinition;
-import org.springframework.transaction.TransactionException;
-import org.springframework.transaction.support.AbstractPlatformTransactionManager;
-import org.springframework.transaction.support.DefaultTransactionStatus;
-
-import org.apache.isis.applib.services.eventbus.EventBusService;
-import org.apache.isis.commons.internal.context._Context;
-import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.core.interaction.session.InteractionFactory;
-import org.apache.isis.core.interaction.session.InteractionTracker;
-import org.apache.isis.core.transaction.events.TransactionAfterBeginEvent;
-import org.apache.isis.core.transaction.events.TransactionAfterCommitEvent;
-import org.apache.isis.core.transaction.events.TransactionAfterRollbackEvent;
-import org.apache.isis.core.transaction.events.TransactionBeforeBeginEvent;
-import org.apache.isis.core.transaction.events.TransactionBeforeCommitEvent;
-import org.apache.isis.core.transaction.events.TransactionBeforeRollbackEvent;
-import org.apache.isis.core.transaction.integration.IsisTransactionAspectSupport;
-import org.apache.isis.core.transaction.integration.IsisTransactionObject;
-import org.apache.isis.core.transaction.integration.IsisTransactionObject.IsisInteractionScopeType;
-
-import lombok.val;
-import lombok.extern.log4j.Log4j2;
-
-//@Service
-//@Named("isisJdoDn5.IsisPlatformTransactionManagerForJdo")
-//@Order(OrderPrecedence.MIDPOINT)
-//@Primary
-//@Qualifier("JdoDN5")
-//@RequiredArgsConstructor(onConstructor_ = {@Inject})
-@Log4j2
-public class IsisPlatformTransactionManagerForJdoNoMore extends AbstractPlatformTransactionManager {
-
- private static final long serialVersionUID = 1L;
-
- private InteractionFactory isisInteractionFactory;
- private EventBusService eventBusService;
- private InteractionTracker isisInteractionTracker;
-
- @Override
- protected Object doGetTransaction() throws TransactionException {
-
- val isInInteraction = isisInteractionTracker.isInInteractionSession();
- log.debug("doGetTransaction isInSession={}", isInInteraction);
-
- val transactionBeforeBegin =
- IsisTransactionAspectSupport
- .currentTransactionObject()
- .map(IsisTransactionObject::getCurrentTransaction)
- .orElse(null);
-
- if(!isInInteraction) {
-
- if(_Context.isJUnitTest()) {
-
- throw _Exceptions.illegalState("No InteractionSession available. "
- + "Transactions are expected to be within scope of an InteractionSession."
- + "\n"
- + "Possible solution: Make sure your JUnit test extends IsisIntegrationTestAbstract.");
-
- } else {
-
- throw _Exceptions.illegalState("No InteractionSession available. "
- + "Transactions are expected to be within scope of an InteractionSession.");
-
- }
-
- }
-
- return IsisTransactionObject.of(transactionBeforeBegin, IsisInteractionScopeType.REQUEST_SCOPED);
-
- }
-
- @Override
- protected void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException {
- IsisTransactionObject txObject = (IsisTransactionObject) transaction;
-
- log.debug("doBegin {}", definition);
- eventBusService.post(new TransactionBeforeBeginEvent(txObject));
-
- val tx = transactionManagerJdo().beginTransaction();
- txObject.setCurrentTransaction(tx);
- IsisTransactionAspectSupport.putTransactionObject(txObject);
-
- eventBusService.post(new TransactionAfterBeginEvent(txObject));
- }
-
- @Override
- protected void doCommit(DefaultTransactionStatus status) throws TransactionException {
- IsisTransactionObject txObject = (IsisTransactionObject) status.getTransaction();
-
- log.debug("doCommit {}", status);
- eventBusService.post(new TransactionBeforeCommitEvent(txObject));
-
- transactionManagerJdo().commitTransaction(txObject);
-
- eventBusService.post(new TransactionAfterCommitEvent(txObject));
-
- cleanUp(txObject);
- }
-
- @Override
- protected void doRollback(DefaultTransactionStatus status) throws TransactionException {
- IsisTransactionObject txObject = (IsisTransactionObject) status.getTransaction();
-
- log.debug("doRollback {}", status);
- eventBusService.post(new TransactionBeforeRollbackEvent(txObject));
-
- transactionManagerJdo().abortTransaction(txObject);
-
- eventBusService.post(new TransactionAfterRollbackEvent(txObject));
-
- cleanUp(txObject);
- }
-
- // -- HELPER
-
- private void cleanUp(IsisTransactionObject txObject) {
- txObject.getCountDownLatch().countDown();
- txObject.setCurrentTransaction(null);
- if(txObject.getIsisInteractionScopeType() == IsisInteractionScopeType.TEST_SCOPED) {
- isisInteractionFactory.closeSessionStack();
- }
- IsisTransactionAspectSupport.clearTransactionObject();
- }
-
- private _TxProcessor transactionManagerJdo() {
- return isisInteractionTracker.currentInteractionSession()
- .map(interaction->interaction.getAttribute(_TxProcessor.class))
- .orElseThrow(()->_Exceptions.unrecoverable("no current _IsisTransactionManagerJdo available"));
- }
-
-}
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/TxManagerInternalFactory.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/TxManagerInternalFactory.java
deleted file mode 100644
index a48e6c4..0000000
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/TxManagerInternalFactory.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.isis.persistence.jdo.integration.transaction;
-
-import org.apache.isis.applib.services.xactn.TransactionalProcessor;
-import org.apache.isis.core.interaction.session.InteractionTracker;
-import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.persistence.jdo.provider.persistence.HasPersistenceManager;
-
-import lombok.val;
-
-public class TxManagerInternalFactory {
-
- public static TransactionalProcessor newTransactionalProcessor(
- MetaModelContext mmc,
- HasPersistenceManager pmProvider) {
-
- val txMan = new _TxProcessor(mmc, pmProvider);
-
- val isisInteractionTracker = mmc.getServiceRegistry()
- .lookupServiceElseFail(InteractionTracker.class);
-
- isisInteractionTracker.currentInteractionSession()
- .map(interaction->interaction.putAttribute(_TxProcessor.class, txMan));
-
- return mmc.getTransactionService();
-
- }
-
-}
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/_Tx.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/_Tx.java
deleted file mode 100644
index cd090ee..0000000
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/_Tx.java
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.isis.persistence.jdo.integration.transaction;
-
-import java.util.UUID;
-import java.util.concurrent.CountDownLatch;
-
-import javax.enterprise.inject.Vetoed;
-
-import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.applib.services.TransactionScopeListener;
-import org.apache.isis.applib.services.TransactionScopeListener.PreCommitPhase;
-import org.apache.isis.applib.services.xactn.Transaction;
-import org.apache.isis.applib.services.xactn.TransactionId;
-import org.apache.isis.applib.services.xactn.TransactionState;
-import org.apache.isis.commons.collections.Can;
-import org.apache.isis.commons.exceptions.IsisException;
-import org.apache.isis.commons.internal.assertions._Assert;
-import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.core.interaction.session.InteractionTracker;
-import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.core.transaction.integration.IsisTransactionFlushException;
-import org.apache.isis.core.transaction.integration.IsisTransactionManagerException;
-import org.apache.isis.persistence.jdo.integration.persistence.JdoPersistenceSession;
-import org.apache.isis.persistence.jdo.provider.persistence.HasPersistenceManager;
-
-import lombok.Getter;
-import lombok.NonNull;
-import lombok.ToString;
-import lombok.val;
-import lombok.extern.log4j.Log4j2;
-
-@Vetoed @Log4j2 @ToString
-class _Tx implements Transaction {
-
- public enum State {
- /**
- * Started, still in progress.
- *
- * <p>
- * May {@link IsisTransaction#flush() flush},
- * {@link IsisTransaction#commit() commit} or
- * {@link IsisTransaction#markAsAborted() abort}.
- */
- IN_PROGRESS(TransactionState.IN_PROGRESS),
- /**
- * Started, but has hit an exception.
- *
- * <p>
- * May not {@link IsisTransaction#flush()} or
- * {@link IsisTransaction#commit() commit} (will throw an
- * {@link IllegalStateException}), but can only
- * {@link IsisTransaction#markAsAborted() abort}.
- *
- * <p>
- * Similar to <tt>setRollbackOnly</tt> in EJBs.
- */
- MUST_ABORT(TransactionState.MUST_ABORT),
- /**
- * Completed, having successfully committed.
- *
- * <p>
- * May not {@link IsisTransaction#flush()} or
- * {@link IsisTransaction#markAsAborted() abort}.
- * {@link IsisTransaction#commit() commit} (will throw
- * {@link IllegalStateException}).
- */
- COMMITTED(TransactionState.COMMITTED),
- /**
- * Completed, having aborted.
- *
- * <p>
- * May not {@link IsisTransaction#flush()},
- * {@link IsisTransaction#commit() commit} or
- * {@link IsisTransaction#markAsAborted() abort} (will throw
- * {@link IllegalStateException}).
- */
- ABORTED(TransactionState.ABORTED);
-
- public final TransactionState transactionState;
-
- State(TransactionState transactionState){
- this.transactionState = transactionState;
- }
-
-
- /**
- * Whether it is valid to {@link _Tx#commit() commit} this
- * {@link _Tx transaction}.
- */
- public boolean canCommit() {
- return this == IN_PROGRESS;
- }
-
- /**
- * Whether it is valid to {@link _Tx#markAsAborted() abort} this
- * {@link _Tx transaction}.
- */
- public boolean canAbort() {
- return this == IN_PROGRESS || this == MUST_ABORT;
- }
-
- /**
- * Whether the {@link _Tx transaction} is complete (and so a
- * new one can be started).
- */
- public boolean isComplete() {
- return this == COMMITTED || this == ABORTED;
- }
-
- public boolean mustAbort() {
- return this == MUST_ABORT;
- }
-
- public TransactionState getTransactionState() {
- return transactionState;
- }
- }
-
- // -- constructor, fields
-
- @Getter @Programmatic
- private final TransactionId id;
-
- @ToString.Exclude
- private final HasPersistenceManager pmProvider;
-
- @ToString.Exclude
- private final InteractionTracker isisInteractionTracker;
-
- @ToString.Exclude
- private final Can<TransactionScopeListener> transactionScopeListeners;
-
- private IsisException abortCause;
-
- public _Tx(
- final MetaModelContext mmc,
- final HasPersistenceManager pmProvider,
- final UUID interactionId,
- final int sequence) {
-
- id = TransactionId.of(interactionId, sequence);
-
- this.pmProvider = pmProvider;
- this.isisInteractionTracker = mmc.getServiceRegistry().lookupServiceElseFail(InteractionTracker.class);
- this.transactionScopeListeners = mmc.getServiceRegistry().select(TransactionScopeListener.class);
-
- this.state = State.IN_PROGRESS;
-
- log.debug("new transaction {}", this);
-
- for (TransactionScopeListener listener : transactionScopeListeners) {
- listener.onTransactionStarted();
- }
-
- }
-
- private final CountDownLatch countDownLatch = new CountDownLatch(1);
-
- // -- state
-
- @Getter
- private State state;
- private void setState(final @NonNull State state) {
- if(this.state == state) {
- return;
- }
- this.state = state;
- if(state.isComplete()) {
- countDownLatch.countDown();
- }
- }
-
- @Override
- public TransactionState getTransactionState() {
-
- if (getState() == null) {
- return TransactionState.NONE;
- }
-
- val transactionState = getState().getTransactionState();
- return transactionState == null
- ? TransactionState.NONE
- : transactionState;
- }
-
- // -- flush
-
- @Override
- public final void flush() {
-
- // have removed THIS guard because we hit a situation where a xactn is aborted
- // from a no-arg action, the Wicket viewer attempts to render a new page that (of course)
- // contains the service menu items, and some of the 'disableXxx()' methods of those
- // service actions perform repository queries (while xactn is still in a state of ABORTED)
- //
- // ensureThatState(getState().canFlush(), is(true), "state is: " + getState());
- //
- log.debug("flush transaction {}", this);
-
- try {
- flushTransaction();
- } catch (final RuntimeException ex) {
- setAbortCause(new IsisTransactionFlushException(ex));
- throw ex;
- }
- }
-
- private void flushTransaction() {
- pmProvider.flushTransaction();
- }
-
- protected JdoPersistenceSession getPersistenceSession() {
- return isisInteractionTracker.currentInteractionSession()
- .map(interaction->interaction.getAttribute(JdoPersistenceSession.class))
- .orElseThrow(()->_Exceptions.unrecoverable("no current JdoPersistenceSession available"));
- }
-
-
- // -- preCommit, commit
-
- void preCommit() {
- _Assert.assertTrue(getState().canCommit());
- _Assert.assertTrue(abortCause == null);
-
- log.debug("preCommit transaction {}", this);
-
- if (getState() == State.COMMITTED) {
- log.info("already committed; ignoring");
- return;
- }
-
- try {
-
- flushTransaction();
-
- notifyPreCommit(PreCommitPhase.PRE_PUBLISHING);
- notifyPreCommit(PreCommitPhase.WHILE_PUBLISHING);
-
- } catch (RuntimeException ex) {
- setAbortCause(new IsisTransactionManagerException(ex));
- throw ex;
- } finally {
- notifyPreCommit(PreCommitPhase.POST_PUBLISHING);
- }
- }
-
- private void notifyPreCommit(PreCommitPhase preCommitPhase) {
- for (val listener : transactionScopeListeners) {
- listener.onPreCommit(preCommitPhase);
- }
- }
-
- void commit() {
- assert getState().canCommit();
- assert abortCause == null;
-
- log.debug("postCommit transaction {}", this);
-
- if (getState() == State.COMMITTED) {
- log.info("already committed; ignoring");
- return;
- }
-
- setState(State.COMMITTED);
-
- }
-
- // -- abortCause, markAsAborted
-
- /**
- * internal API called by IsisTransactionManager only
- */
- final void markAsAborted() {
- assert getState().canAbort();
-
- log.info("abort transaction {}", this);
- setState(State.ABORTED);
- }
-
-
- /**
- * Indicate that the transaction must be aborted, and that there is
- * an unhandled exception to be rendered somehow.
- *
- * <p>
- * If the cause is subsequently rendered by code higher up the stack, then the
- * cause can be {@link #clearAbortCause() cleared}. Note that this keeps the transaction in a state of
- * {@link State#MUST_ABORT}.
- *
- * <p>
- * If the cause is to be discarded completely (eg background command execution), then
- * {@link #clearAbortCauseAndContinue()} can be used.
- */
- public void setAbortCause(IsisException abortCause) {
- setState(State.MUST_ABORT);
- this.abortCause = abortCause;
- }
-
- public IsisException getAbortCause() {
- return abortCause;
- }
-
- /**
- * If the cause has been rendered higher up in the stack, then clear the cause so that
- * it won't be picked up and rendered elsewhere.
- *
- * <p>
- * for framework internal use only.
- * </p>
- *
- */
- public void clearAbortCause() {
- abortCause = null;
- }
-
- public void clearAbortCauseAndContinue() {
- setState(State.IN_PROGRESS);
- clearAbortCause();
- }
-
-
-}
-
-
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/_TxProcessor.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/_TxProcessor.java
deleted file mode 100644
index 7624451..0000000
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/_TxProcessor.java
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.isis.persistence.jdo.integration.transaction;
-
-import java.util.function.Supplier;
-
-import javax.enterprise.inject.Vetoed;
-
-import org.apache.isis.applib.services.iactn.Interaction;
-import org.apache.isis.applib.services.iactn.InteractionContext;
-import org.apache.isis.commons.exceptions.IsisException;
-import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.core.transaction.integration.IsisTransactionAspectSupport;
-import org.apache.isis.core.transaction.integration.IsisTransactionManagerException;
-import org.apache.isis.core.transaction.integration.IsisTransactionObject;
-import org.apache.isis.persistence.jdo.provider.persistence.HasPersistenceManager;
-
-import lombok.val;
-import lombok.extern.log4j.Log4j2;
-
-@Vetoed @Log4j2
-class _TxProcessor {
-
- // -- constructor, fields
-
- private final MetaModelContext mmc;
- private final Supplier<InteractionContext> interactionContextProvider;
- private final HasPersistenceManager pmProvider;
-
- _TxProcessor(
- MetaModelContext mmc,
- HasPersistenceManager pmProvider) {
-
- this.mmc = mmc;
- this.interactionContextProvider = ()->mmc.getServiceRegistry().lookupServiceElseFail(InteractionContext.class);
- this.pmProvider = pmProvider;
- }
-
- public _Tx beginTransaction() {
-
- val txInProgress = IsisTransactionAspectSupport.isTransactionInProgress();
- if (txInProgress) {
-
- val txObject = IsisTransactionAspectSupport
- .currentTransactionObject()
- .orElseThrow(()->_Exceptions.unrecoverable("no current IsisTransactionObject available"));
-
- txObject.incTransactionNestingLevel();
- val nestingLevel = txObject.getTransactionNestingLevel();
-
- if (log.isDebugEnabled()) {
- log.debug("startTransaction: nesting-level {}->{}",
- nestingLevel - 1,
- nestingLevel);
- }
-
- return (_Tx) txObject.getCurrentTransaction();
-
- } else {
-
- val interaction = interactionContextProvider.get().currentInteractionElseFail();
-
- val command = interaction.getCommand();
- val transactionId = command.getUniqueId();
-
- val currentTransaction = new _Tx(
- mmc,
- pmProvider,
- transactionId,
- interaction.next(Interaction.Sequence.TRANSACTION.id()));
-
- pmProvider.startTransaction();
-
- if (log.isDebugEnabled()) {
- log.debug("startTransaction: top-level");
- }
-
- return currentTransaction;
- }
-
- }
-
-
- public void flushTransaction(_Tx transaction) {
- if (transaction != null) {
- log.debug("flushTransaction");
- transaction.flush();
- }
- }
-
- /**
- * Ends the transaction if nesting level is 0 (but will abort the transaction instead,
- * even if nesting level is not 0, if an {@link _Tx#getAbortCause() abort cause}
- * has been {@link _Tx#setAbortCause(IsisException) set}.
- *
- * <p>
- * If in the process of committing the transaction an exception is thrown, then this will
- * be handled and will abort the transaction instead.
- *
- * <p>
- * If an abort cause has been set (or an exception occurs), then will throw this
- * exception in turn.
- */
- public void commitTransaction(IsisTransactionObject txObject) {
-
- val transaction = (_Tx) txObject.getCurrentTransaction();
-
- if (transaction == null) {
- // allow this method to be called >1 with no adverse affects
-
- if (log.isDebugEnabled()) {
- log.debug("endTransaction: no transaction exists");
- }
-
- return;
- }
-
- if (transaction.getState().isComplete()) {
- // allow this method to be called >1 with no adverse affects
-
- if (log.isDebugEnabled()) {
- log.debug("endTransaction: previous transaction completed");
- }
-
- return;
- }
-
- val transactionLevel = txObject.getTransactionNestingLevel();
- val isTopLevel = txObject.isTopLevel();
-
- if (log.isDebugEnabled()) {
- log.debug("endTransaction: level {}->{}", transactionLevel, transactionLevel - 1);
- }
-
- try {
- endTransactionInternal(txObject);
- } finally {
- val tx = (_Tx) txObject.getCurrentTransaction();
- if(tx==null) {
- log.error("race condition when ending the current transaction object");
- } else {
- val state = tx.getState();
- if(isTopLevel && !state.isComplete()) {
- log.error("endTransaction: when top-level, "
- + "transactionState is expected COMMITTED or ABORTED but was: '{}'", state);
- }
- }
- }
- }
-
- private void endTransactionInternal(IsisTransactionObject txObject) {
-
- val transaction = (_Tx) txObject.getCurrentTransaction();
-
- // terminate the transaction early if an abort cause was already set.
- RuntimeException abortCause = transaction.getAbortCause();
- if(transaction.getState().mustAbort()) {
-
- if (log.isDebugEnabled()) {
- log.debug("endTransaction: aborting instead [EARLY TERMINATION], abort cause '{}' has been set", abortCause.getMessage());
- }
- try {
- abortTransaction(txObject);
-
- // just in case any different exception was raised...
- val currentTx = this.getCurrentTransaction();
- if(currentTx!=null && currentTx.getAbortCause()!=null) {
- abortCause = currentTx.getAbortCause();
- }
-
- } catch(RuntimeException ex) {
-
- abortCause = ex;
-
- }
-
- if(abortCause != null) {
-
- // re-introduced the throwing of exceptions in 1.15.1 (same as 1.14.x)
-
- // in 1.15.0 we were not throwing exceptions at this point, resulting in JDOUserException errors
- // (eg malformed SQL) simply being silently ignored
-
- // the reason that no exceptions were being thrown in 1.15.0 was because it was observed that
- // throwing exceptions always resulted in forwarding to the error page, even if the error had been
- // recognised at the UI layer. This was the rationale given, at least.
- //
- // Not certain now it is correct; if it was to improve the UI experience.
- //
- // Certainly swallowing severe exceptions is much less acceptable. Therefore reverting.
-
- throw abortCause;
-
-
- } else {
- // assume that any rendering of the problem has been done lower down the stack.
- return;
- }
- }
-
- if(!txObject.isTopLevel()) {
- txObject.decTransactionNestingLevel();
- return;
- }
-
- //
- // TODO: granted, this is some fairly byzantine coding. but I'm trying to account for different types
- // of object store implementations that could start throwing exceptions at any stage.
- // once the contract/API for the objectstore is better tied down, hopefully can simplify this...
- //
-
- if(abortCause == null) {
-
- if (log.isDebugEnabled()) {
- log.debug("endTransaction: committing");
- }
-
- try {
-
- val currentTx = this.getCurrentTransaction();
- if(currentTx!=null) {
- currentTx.preCommit();
- }
-
- } catch(Exception ex) {
- // just in case any new exception was raised...
-
- // this bizarre code because an InvocationTargetException (which is not a RuntimeException) was
- // being thrown due to a coding error in a domain object
- abortCause = ex instanceof RuntimeException ? (RuntimeException) ex : new RuntimeException(ex);
-
- val currentTx = this.getCurrentTransaction();
- if(currentTx!=null) {
- currentTx.setAbortCause(new IsisTransactionManagerException(ex));
- }
-
- }
- }
-
- if(abortCause == null) {
- try {
-
- pmProvider.endTransaction();
- } catch(Exception ex) {
- // just in case any new exception was raised...
- abortCause = ex instanceof RuntimeException ? (RuntimeException) ex : new RuntimeException(ex);
-
- // hacky... moving the transaction back to something other than COMMITTED
- val currentTx = this.getCurrentTransaction();
- if(currentTx!=null) {
- currentTx.setAbortCause(new IsisTransactionManagerException(ex));
- }
- }
- }
-
-
- // previously we called __isis_endRequest here on all RequestScopedServices. This is now
- // done later, in PersistenceSession#close(). If we introduce support for @TransactionScoped
- // services, then this would be the place to finalize them.
-
- //
- // finally, if an exception was thrown, we rollback the transaction
- //
-
- if(abortCause != null) {
-
- if (log.isDebugEnabled()) {
- log.debug("endTransaction: aborting instead, abort cause has been set");
- }
- try {
- abortTransaction(txObject);
- } catch(RuntimeException ex) {
- // ignore; nothing to do:
- // * we want the existing abortCause to be available
- // * the transactionLevel is correctly now at 0.
- }
-
- throw abortCause;
- } else {
-
- // keeping things in sync
- val currentTx = this.getCurrentTransaction();
- if(currentTx!=null) {
- currentTx.commit();
- }
- }
-
- }
-
- public void abortTransaction(IsisTransactionObject txObject) {
- val transaction = (_Tx) txObject.getCurrentTransaction();
- if (transaction != null) {
- transaction.markAsAborted();
- pmProvider.abortTransaction();
- txObject.clear();
- }
- }
-
- // -- HELPER
-
- private _Tx getCurrentTransaction() {
- return IsisTransactionAspectSupport.currentTransactionObject()
- .map(IsisTransactionObject::getCurrentTransaction)
- .map(_Tx.class::cast)
- .orElse(null);
- }
-
-}
diff --git a/valuetypes/sse/ui/wicket/src/main/java/org/apache/isis/valuetypes/sse/ui/wkt/services/SseServiceDefault.java b/valuetypes/sse/ui/wicket/src/main/java/org/apache/isis/valuetypes/sse/ui/wkt/services/SseServiceDefault.java
index 4d7d7b1..20b62d3 100644
--- a/valuetypes/sse/ui/wicket/src/main/java/org/apache/isis/valuetypes/sse/ui/wkt/services/SseServiceDefault.java
+++ b/valuetypes/sse/ui/wicket/src/main/java/org/apache/isis/valuetypes/sse/ui/wkt/services/SseServiceDefault.java
@@ -40,9 +40,9 @@ import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.apache.isis.applib.annotation.OrderPrecedence;
+import org.apache.isis.applib.services.xactn.TransactionService;
import org.apache.isis.commons.internal.collections._Lists;
import org.apache.isis.core.interaction.session.InteractionFactory;
-import org.apache.isis.core.transaction.integration.IsisTransactionAspectSupport;
import org.apache.isis.valuetypes.sse.applib.annotations.SseSource;
import org.apache.isis.valuetypes.sse.applib.service.SseChannel;
import org.apache.isis.valuetypes.sse.applib.service.SseService;
@@ -69,7 +69,7 @@ import lombok.extern.log4j.Log4j2;
@Log4j2
public class SseServiceDefault implements SseService {
- //@Inject private TransactionService transactionService;
+ @Inject private TransactionService transactionService;
@Inject private InteractionFactory isisInteractionFactory;
private final EventStreamPool eventStreamPool = new EventStreamPool();
@@ -95,15 +95,12 @@ public class SseServiceDefault implements SseService {
break; // fall through
}
- val callingThread_TransactionLatch = IsisTransactionAspectSupport.transactionLatch();
-
// spawn a new thread that gets its own session
CompletableFuture.runAsync(()->{
- // wait for calling thread to commit its current transaction
- callingThread_TransactionLatch.await();
-
- isisInteractionFactory.runAnonymous(()->run(task));
+ isisInteractionFactory.runAnonymous(()->{
+ transactionService.runWithinCurrentTransactionElseCreateNew(()->run(task));
+ });
}, executor);