diff --git a/src/main/java/li/strolch/agent/api/ElementMap.java b/src/main/java/li/strolch/agent/api/ElementMap.java index ba5a078b8..a46a97fb6 100644 --- a/src/main/java/li/strolch/agent/api/ElementMap.java +++ b/src/main/java/li/strolch/agent/api/ElementMap.java @@ -50,9 +50,9 @@ public interface ElementMap { public void addAll(StrolchTransaction tx, List elements); - public void update(StrolchTransaction tx, T element); + public T update(StrolchTransaction tx, T element); - public void updateAll(StrolchTransaction tx, List elements); + public List updateAll(StrolchTransaction tx, List elements); public void remove(StrolchTransaction tx, T element); diff --git a/src/main/java/li/strolch/agent/impl/CachedElementMap.java b/src/main/java/li/strolch/agent/impl/CachedElementMap.java index b4a90778c..ab1e8b875 100644 --- a/src/main/java/li/strolch/agent/impl/CachedElementMap.java +++ b/src/main/java/li/strolch/agent/impl/CachedElementMap.java @@ -130,7 +130,7 @@ public abstract class CachedElementMap implements Elem } @Override - public void update(StrolchTransaction tx, T element) { + public T update(StrolchTransaction tx, T element) { DBC.PRE.assertNotNull("Transaction may not be null!", tx); //$NON-NLS-1$ DBC.PRE.assertNotNull("Element may not be null!", element); //$NON-NLS-1$ @@ -141,14 +141,17 @@ public abstract class CachedElementMap implements Elem throw new StrolchPersistenceException(msg); } + T replacedElement; synchronized (byType) { if (byType.remove(element.getId()) == null) { msg = MessageFormat.format(msg, element.getLocator()); throw new StrolchPersistenceException(msg); } - byType.put(element.getId(), element); + replacedElement = byType.put(element.getId(), element); getDao(tx).update(element); } + + return replacedElement; } @Override @@ -184,8 +187,8 @@ public abstract class CachedElementMap implements Elem /** * Special method used when starting the container to cache the values. Not to be used anywhere else but from the - * {@link CachedRealm} and of course through the {@link #add(StrolchTransaction, StrolchElement)}-call - * to not duplicate code + * {@link CachedRealm} and of course through the {@link #add(StrolchTransaction, StrolchElement)}-call to not + * duplicate code * * @param element * @param tx @@ -275,18 +278,20 @@ public abstract class CachedElementMap implements Elem } @Override - public void updateAll(StrolchTransaction tx, List elements) { + public List updateAll(StrolchTransaction tx, List elements) { DBC.PRE.assertNotNull("Transaction may not be null!", tx); //$NON-NLS-1$ DBC.PRE.assertNotNull("Elements may not be null!", elements); //$NON-NLS-1$ if (elements.isEmpty()) - return; + return Collections.emptyList(); // sort elements by type Map> map = sortElementsToType(elements); String msg = "The element {0} can not be updated as it does not exist!"; //$NON-NLS-1$ + List replacedElements = new ArrayList<>(elements.size()); + // update elements for (String type : map.keySet()) { List list = map.get(type); @@ -304,7 +309,7 @@ public abstract class CachedElementMap implements Elem msg = MessageFormat.format(msg, element.getLocator()); throw new StrolchPersistenceException(msg); } - byType.put(element.getId(), element); + replacedElements.add(byType.put(element.getId(), element)); } } } @@ -312,6 +317,8 @@ public abstract class CachedElementMap implements Elem // last is to perform DB changes getDao(tx).updateAll(elements); + + return replacedElements; } @Override diff --git a/src/main/java/li/strolch/agent/impl/TransactionalElementMap.java b/src/main/java/li/strolch/agent/impl/TransactionalElementMap.java index 8f5dae481..13a412eda 100644 --- a/src/main/java/li/strolch/agent/impl/TransactionalElementMap.java +++ b/src/main/java/li/strolch/agent/impl/TransactionalElementMap.java @@ -74,8 +74,9 @@ public abstract class TransactionalElementMap implemen } @Override - public void update(StrolchTransaction tx, T element) { + public T update(StrolchTransaction tx, T element) { getDao(tx).update(element); + return element; } @Override @@ -94,7 +95,8 @@ public abstract class TransactionalElementMap implemen } @Override - public void updateAll(StrolchTransaction tx, List elements) { + public List updateAll(StrolchTransaction tx, List elements) { getDao(tx).updateAll(elements); + return elements; } } diff --git a/src/main/java/li/strolch/persistence/api/AbstractTransaction.java b/src/main/java/li/strolch/persistence/api/AbstractTransaction.java index 484fa6f51..b2060d8a9 100644 --- a/src/main/java/li/strolch/persistence/api/AbstractTransaction.java +++ b/src/main/java/li/strolch/persistence/api/AbstractTransaction.java @@ -56,7 +56,6 @@ public abstract class AbstractTransaction implements StrolchTransaction { private ObserverHandler observerHandler; private boolean suppressUpdates; private TransactionResult txResult; - private boolean open; private Set lockedElements; @@ -65,12 +64,32 @@ public abstract class AbstractTransaction implements StrolchTransaction { this.lockedElements = new HashSet<>(); this.closeStrategy = TransactionCloseStrategy.COMMIT; this.txResult = new TransactionResult(getRealmName(), System.nanoTime(), new Date()); - this.open = true; + this.txResult.setState(TransactionState.OPEN); } @Override public boolean isOpen() { - return this.open; + return this.txResult.getState() == TransactionState.OPEN; + } + + @Override + public boolean isRollingBack() { + return this.txResult.getState() == TransactionState.ROLLING_BACK; + } + + @Override + public boolean isCommitting() { + return this.txResult.getState() == TransactionState.COMMITTING; + } + + @Override + public boolean isCommitted() { + return this.txResult.getState() == TransactionState.COMMITTED; + } + + @Override + public boolean isRolledBack() { + return this.txResult.getState() == TransactionState.ROLLED_BACK; } @Override @@ -209,9 +228,11 @@ public abstract class AbstractTransaction implements StrolchTransaction { } try { + this.txResult.setState(TransactionState.COMMITTING); commit(this.txResult); handleCommit(start); } catch (Exception e) { + this.txResult.setState(TransactionState.ROLLING_BACK); handleFailure(start, e); } finally { unlockElements(); @@ -239,7 +260,6 @@ public abstract class AbstractTransaction implements StrolchTransaction { protected abstract void rollback(TransactionResult txResult) throws Exception; private void handleCommit(long start) { - this.open = false; long end = System.nanoTime(); long txDuration = end - txResult.getStartNanos(); @@ -272,7 +292,6 @@ public abstract class AbstractTransaction implements StrolchTransaction { } private void handleRollback(long start) { - this.open = false; long end = System.nanoTime(); long txDuration = end - this.txResult.getStartNanos(); @@ -284,7 +303,6 @@ public abstract class AbstractTransaction implements StrolchTransaction { } protected void handleFailure(long closeStartNanos, Exception e) { - this.open = false; long end = System.nanoTime(); long txDuration = end - this.txResult.getStartNanos(); diff --git a/src/main/java/li/strolch/persistence/api/StrolchTransaction.java b/src/main/java/li/strolch/persistence/api/StrolchTransaction.java index 974e2aa3b..74686c2e1 100644 --- a/src/main/java/li/strolch/persistence/api/StrolchTransaction.java +++ b/src/main/java/li/strolch/persistence/api/StrolchTransaction.java @@ -45,6 +45,14 @@ public interface StrolchTransaction extends AutoCloseable { public boolean isOpen(); + public boolean isRollingBack(); + + public boolean isCommitting(); + + public boolean isCommitted(); + + public boolean isRolledBack(); + public ResourceMap getResourceMap(); public OrderMap getOrderMap(); diff --git a/src/main/java/li/strolch/persistence/api/TransactionState.java b/src/main/java/li/strolch/persistence/api/TransactionState.java index 3b922460a..6405bfe4d 100644 --- a/src/main/java/li/strolch/persistence/api/TransactionState.java +++ b/src/main/java/li/strolch/persistence/api/TransactionState.java @@ -17,7 +17,9 @@ package li.strolch.persistence.api; public enum TransactionState { OPEN, // + COMMITTING, // + ROLLING_BACK, // COMMITTED, // - ROLLED_BACK, // + ROLLED_BACK, FAILED; } diff --git a/src/main/java/li/strolch/service/api/Command.java b/src/main/java/li/strolch/service/api/Command.java index 34d1a80da..cdea42493 100644 --- a/src/main/java/li/strolch/service/api/Command.java +++ b/src/main/java/li/strolch/service/api/Command.java @@ -74,4 +74,6 @@ public abstract class Command implements Restrictable { } public abstract void doCommand(); + + public abstract void undo(); }