From 07daf34f86a349cb38ffd929bfe539ea1e4cf47b Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Mon, 8 Aug 2016 09:30:56 +0200 Subject: [PATCH] [Major] Implemented opt-in versioning - fixing remaining PostgreSQL DAO tests --- .../agent/impl/TransactionalElementMap.java | 16 +++++++- .../persistence/api/AbstractTransaction.java | 20 ++++++---- .../strolch/persistence/api/StrolchDao.java | 4 ++ .../persistence/inmemory/InMemoryDao.java | 5 +++ .../inmemory/InMemoryTransaction.java | 9 ++--- .../PostgreSqlStrolchTransaction.java | 11 +++--- .../persistence/postgresql/PostgresqlDao.java | 38 +++++++++---------- .../strolch/persistence/xml/AbstractDao.java | 6 +++ .../xml/XmlStrolchTransaction.java | 10 ++--- 9 files changed, 73 insertions(+), 46 deletions(-) diff --git a/li.strolch.agent/src/main/java/li/strolch/agent/impl/TransactionalElementMap.java b/li.strolch.agent/src/main/java/li/strolch/agent/impl/TransactionalElementMap.java index efe7833e6..7c078c967 100644 --- a/li.strolch.agent/src/main/java/li/strolch/agent/impl/TransactionalElementMap.java +++ b/li.strolch.agent/src/main/java/li/strolch/agent/impl/TransactionalElementMap.java @@ -254,6 +254,7 @@ public abstract class TransactionalElementMap impl Version.setInitialVersionFor(element, tx.getCertificate().getUsername()); getDao(tx).save(element); + getDao(tx).flush(); } @Override @@ -266,6 +267,7 @@ public abstract class TransactionalElementMap impl } getDao(tx).saveAll(elements); + getDao(tx).flush(); } @Override @@ -276,6 +278,7 @@ public abstract class TransactionalElementMap impl Version.setInitialVersionFor(element, tx.getCertificate().getUsername()); getDao(tx).update(element); + getDao(tx).flush(); } @Override @@ -288,6 +291,7 @@ public abstract class TransactionalElementMap impl } getDao(tx).updateAll(elements); + getDao(tx).flush(); } @Override @@ -299,6 +303,7 @@ public abstract class TransactionalElementMap impl Version.setInitialVersionFor(element, tx.getCertificate().getUsername()); getDao(tx).remove(element); } + getDao(tx).flush(); } @Override @@ -315,16 +320,21 @@ public abstract class TransactionalElementMap impl } else { getDao(tx).removeAll(elements); } + getDao(tx).flush(); } @Override public long removeAll(StrolchTransaction tx) { - return getDao(tx).removeAll(); + long removed = getDao(tx).removeAll(); + getDao(tx).flush(); + return removed; } @Override public long removeAllBy(StrolchTransaction tx, String type) { - return getDao(tx).removeAllBy(type); + long removed = getDao(tx).removeAllBy(type); + getDao(tx).flush(); + return removed; } @Override @@ -349,6 +359,7 @@ public abstract class TransactionalElementMap impl // save the new version getDao(tx).update(clone); + getDao(tx).flush(); // and return new version return clone; @@ -369,6 +380,7 @@ public abstract class TransactionalElementMap impl } getDao(tx).removeVersion(current); + getDao(tx).flush(); } protected abstract void assertIsRefParam(Parameter refP); diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java b/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java index 51a3e0139..1520981d6 100644 --- a/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java +++ b/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java @@ -119,6 +119,10 @@ public abstract class AbstractTransaction implements StrolchTransaction { this.txResult.setState(TransactionState.OPEN); } + public TransactionResult getTxResult() { + return this.txResult; + } + @Override public TransactionState getState() { return this.txResult.getState(); @@ -534,7 +538,7 @@ public abstract class AbstractTransaction implements StrolchTransaction { try { validateCommands(); doCommands(); - writeChanges(this.txResult); + writeChanges(); } catch (Exception e) { this.closeStrategy = TransactionCloseStrategy.ROLLBACK; @@ -553,7 +557,7 @@ public abstract class AbstractTransaction implements StrolchTransaction { validateCommands(); doCommands(); - writeChanges(this.txResult); + writeChanges(); long auditTrailDuration = writeAuditTrail(); long updateObserversDuration = updateObservers(); @@ -573,7 +577,7 @@ public abstract class AbstractTransaction implements StrolchTransaction { } catch (Exception ex) { logger.error("Failed to commit transaction and then undo commands due to " + ex.getMessage(), ex); try { - rollback(this.txResult); + rollback(); handleRollback(start); } catch (Exception exc) { logger.error("Failed to roll back after failing to undo commands: " + exc.getMessage(), exc); //$NON-NLS-1$ @@ -582,7 +586,7 @@ public abstract class AbstractTransaction implements StrolchTransaction { } try { - rollback(this.txResult); + rollback(); handleRollback(start); } catch (Exception ex) { logger.error("Failed to commit transaction and then rollback due to " + ex.getMessage(), ex); @@ -607,7 +611,7 @@ public abstract class AbstractTransaction implements StrolchTransaction { try { this.txResult.setState(TransactionState.ROLLING_BACK); undoCommands(); - rollback(this.txResult); + rollback(); handleRollback(start); this.txResult.setState(TransactionState.ROLLED_BACK); } catch (Exception e) { @@ -635,7 +639,7 @@ public abstract class AbstractTransaction implements StrolchTransaction { long auditTrailDuration = writeAuditTrail(); // rollback and release any resources - rollback(this.txResult); + rollback(); handleDoNothing(start, auditTrailDuration); this.txResult.setState(TransactionState.CLOSED); @@ -647,9 +651,9 @@ public abstract class AbstractTransaction implements StrolchTransaction { } } - protected abstract void writeChanges(TransactionResult txResult) throws Exception; + protected abstract void writeChanges() throws Exception; - protected abstract void rollback(TransactionResult txResult) throws Exception; + protected abstract void rollback() throws Exception; protected abstract void commit() throws Exception; diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchDao.java b/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchDao.java index c39e60e9e..05c0df5aa 100644 --- a/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchDao.java +++ b/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchDao.java @@ -292,4 +292,8 @@ public interface StrolchDao { */ public void removeVersion(T element) throws StrolchPersistenceException; + /** + * Causes the DAO to flush any actions which have not yet been sent to the underlying persistence layer + */ + public void flush(); } diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryDao.java b/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryDao.java index b2e1b2619..4d11d08f7 100644 --- a/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryDao.java +++ b/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryDao.java @@ -312,4 +312,9 @@ public class InMemoryDao implements StrolchDao byType.remove(element.getId()); } } + + @Override + public void flush() { + // nothing to do + } } diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryTransaction.java b/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryTransaction.java index de9674fd0..9090aa3fb 100644 --- a/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryTransaction.java +++ b/li.strolch.agent/src/main/java/li/strolch/persistence/inmemory/InMemoryTransaction.java @@ -18,7 +18,6 @@ package li.strolch.persistence.inmemory; import li.strolch.agent.api.StrolchRealm; import li.strolch.persistence.api.AbstractTransaction; import li.strolch.persistence.api.PersistenceHandler; -import li.strolch.persistence.api.TransactionResult; import li.strolch.persistence.api.TransactionState; import li.strolch.privilege.model.Certificate; import li.strolch.runtime.privilege.PrivilegeHandler; @@ -34,13 +33,13 @@ public class InMemoryTransaction extends AbstractTransaction { } @Override - protected void writeChanges(TransactionResult txResult) throws Exception { - txResult.setState(TransactionState.COMMITTED); + protected void writeChanges() throws Exception { + getTxResult().setState(TransactionState.COMMITTED); } @Override - protected void rollback(TransactionResult txResult) throws Exception { - txResult.setState(TransactionState.ROLLED_BACK); + protected void rollback() throws Exception { + getTxResult().setState(TransactionState.ROLLED_BACK); } @Override diff --git a/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlStrolchTransaction.java b/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlStrolchTransaction.java index b230ce54c..578c774a8 100644 --- a/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlStrolchTransaction.java +++ b/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlStrolchTransaction.java @@ -27,7 +27,6 @@ import li.strolch.persistence.api.AuditDao; import li.strolch.persistence.api.OrderDao; import li.strolch.persistence.api.PersistenceHandler; import li.strolch.persistence.api.ResourceDao; -import li.strolch.persistence.api.TransactionResult; import li.strolch.privilege.model.Certificate; import li.strolch.runtime.privilege.PrivilegeHandler; @@ -49,21 +48,21 @@ public class PostgreSqlStrolchTransaction extends AbstractTransaction { } @Override - protected void writeChanges(TransactionResult txResult) throws Exception { + protected void writeChanges() throws Exception { // first perform DAOs if (this.orderDao != null) - this.orderDao.commit(txResult); + this.orderDao.flush(); if (this.resourceDao != null) - this.resourceDao.commit(txResult); + this.resourceDao.flush(); if (this.activityDao != null) - this.activityDao.commit(txResult); + this.activityDao.flush(); // don't commit the connection, this is done in postCommit when we close the connection } @Override - protected void rollback(TransactionResult txResult) throws Exception { + protected void rollback() throws Exception { if (this.connection != null) { try { this.connection.rollback(); diff --git a/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgresqlDao.java b/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgresqlDao.java index f8cfa4792..8f6ed3933 100644 --- a/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgresqlDao.java +++ b/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgresqlDao.java @@ -28,7 +28,6 @@ import java.util.Set; import li.strolch.model.StrolchRootElement; import li.strolch.persistence.api.StrolchDao; import li.strolch.persistence.api.StrolchPersistenceException; -import li.strolch.persistence.api.TransactionResult; @SuppressWarnings("nls") public abstract class PostgresqlDao implements StrolchDao { @@ -471,21 +470,23 @@ public abstract class PostgresqlDao implements Str throw new StrolchPersistenceException(msg); } - // - sql = "update " + getTableName() + " set latest = true where type = ? and id = ? and version = ?"; - try (PreparedStatement updateStmt = tx().getConnection().prepareStatement(sql)) { - int previousVersion = element.getVersion().getPreviousVersion(); - updateStmt.setString(1, element.getType()); - updateStmt.setString(2, element.getId()); - updateStmt.setInt(3, previousVersion); + if (!element.getVersion().isFirstVersion()) { + sql = "update " + getTableName() + " set latest = true where type = ? and id = ? and version = ?"; + try (PreparedStatement updateStmt = tx().getConnection().prepareStatement(sql)) { + int previousVersion = element.getVersion().getPreviousVersion(); + updateStmt.setString(1, element.getType()); + updateStmt.setString(2, element.getId()); + updateStmt.setInt(3, previousVersion); + + modCount = updateStmt.executeUpdate(); + if (modCount != 1) { + String msg = "Expected to update 1 element with id {0} but SQL statement modified {1} elements! Verify that element {2} with version {3} exists!"; + msg = MessageFormat.format(msg, element.getId(), modCount, element.getLocator(), + previousVersion); + throw new StrolchPersistenceException(msg); + } - modCount = updateStmt.executeUpdate(); - if (modCount != 1) { - String msg = "Expected to update 1 element with id {0} but SQL statement modified {1} elements! Verify that element {2} with version {3} exists!"; - msg = MessageFormat.format(msg, element.getId(), modCount, element.getLocator(), previousVersion); - throw new StrolchPersistenceException(msg); } - } } catch (SQLException e) { @@ -519,15 +520,12 @@ public abstract class PostgresqlDao implements Str } } - void commit(TransactionResult txResult) { + @Override + public void flush() { // even though we support rollback we can clear the commands here even if we performed them because the DB transaction will be rolled back for (DaoCommand command : this.commands) { - command.doComand(txResult); + command.doComand(tx().getTxResult()); } this.commands.clear(); } - - void rollback() { - this.commands.clear(); - } } diff --git a/li.strolch.persistence.xml/src/main/java/li/strolch/persistence/xml/AbstractDao.java b/li.strolch.persistence.xml/src/main/java/li/strolch/persistence/xml/AbstractDao.java index ed37fee50..cd36f7372 100644 --- a/li.strolch.persistence.xml/src/main/java/li/strolch/persistence/xml/AbstractDao.java +++ b/li.strolch.persistence.xml/src/main/java/li/strolch/persistence/xml/AbstractDao.java @@ -188,4 +188,10 @@ public abstract class AbstractDao implements Strol // TODO Auto-generated method stub throw new UnsupportedOperationException("not yet implemented!"); } + + @Override + public void flush() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("not yet implemented!"); + } } diff --git a/li.strolch.persistence.xml/src/main/java/li/strolch/persistence/xml/XmlStrolchTransaction.java b/li.strolch.persistence.xml/src/main/java/li/strolch/persistence/xml/XmlStrolchTransaction.java index 02916aa12..e4268aedc 100644 --- a/li.strolch.persistence.xml/src/main/java/li/strolch/persistence/xml/XmlStrolchTransaction.java +++ b/li.strolch.persistence.xml/src/main/java/li/strolch/persistence/xml/XmlStrolchTransaction.java @@ -43,21 +43,21 @@ public class XmlStrolchTransaction extends AbstractTransaction { } @Override - protected void writeChanges(li.strolch.persistence.api.TransactionResult txResult) throws Exception { + protected void writeChanges() throws Exception { TransactionResult result = new TransactionResult(); this.tx.setTransactionResult(result); this.tx.autoCloseableCommit(); Set keys = result.getKeys(); for (String key : keys) { ModificationResult modificationResult = result.getModificationResult(key); - txResult.incCreated(modificationResult.getCreated().size()); - txResult.incUpdated(modificationResult.getUpdated().size()); - txResult.incDeleted(modificationResult.getDeleted().size()); + getTxResult().incCreated(modificationResult.getCreated().size()); + getTxResult().incUpdated(modificationResult.getUpdated().size()); + getTxResult().incDeleted(modificationResult.getDeleted().size()); } } @Override - protected void rollback(li.strolch.persistence.api.TransactionResult txResult) throws Exception { + protected void rollback() throws Exception { this.tx.autoCloseableRollback(); }