[Major] Implemented opt-in versioning

- fixing remaining PostgreSQL DAO tests
This commit is contained in:
Robert von Burg 2016-08-08 09:30:56 +02:00
parent 8c4c8e539e
commit 07daf34f86
9 changed files with 73 additions and 46 deletions

View File

@ -254,6 +254,7 @@ public abstract class TransactionalElementMap<T extends StrolchRootElement> impl
Version.setInitialVersionFor(element, tx.getCertificate().getUsername());
getDao(tx).save(element);
getDao(tx).flush();
}
@Override
@ -266,6 +267,7 @@ public abstract class TransactionalElementMap<T extends StrolchRootElement> impl
}
getDao(tx).saveAll(elements);
getDao(tx).flush();
}
@Override
@ -276,6 +278,7 @@ public abstract class TransactionalElementMap<T extends StrolchRootElement> impl
Version.setInitialVersionFor(element, tx.getCertificate().getUsername());
getDao(tx).update(element);
getDao(tx).flush();
}
@Override
@ -288,6 +291,7 @@ public abstract class TransactionalElementMap<T extends StrolchRootElement> impl
}
getDao(tx).updateAll(elements);
getDao(tx).flush();
}
@Override
@ -299,6 +303,7 @@ public abstract class TransactionalElementMap<T extends StrolchRootElement> impl
Version.setInitialVersionFor(element, tx.getCertificate().getUsername());
getDao(tx).remove(element);
}
getDao(tx).flush();
}
@Override
@ -315,16 +320,21 @@ public abstract class TransactionalElementMap<T extends StrolchRootElement> 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<T extends StrolchRootElement> 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<T extends StrolchRootElement> impl
}
getDao(tx).removeVersion(current);
getDao(tx).flush();
}
protected abstract void assertIsRefParam(Parameter<?> refP);

View File

@ -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;

View File

@ -292,4 +292,8 @@ public interface StrolchDao<T extends StrolchRootElement> {
*/
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();
}

View File

@ -312,4 +312,9 @@ public class InMemoryDao<T extends StrolchRootElement> implements StrolchDao<T>
byType.remove(element.getId());
}
}
@Override
public void flush() {
// nothing to do
}
}

View File

@ -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

View File

@ -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();

View File

@ -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<T extends StrolchRootElement> implements StrolchDao<T> {
@ -471,21 +470,23 @@ public abstract class PostgresqlDao<T extends StrolchRootElement> 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<T extends StrolchRootElement> 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();
}
}

View File

@ -188,4 +188,10 @@ public abstract class AbstractDao<T extends StrolchRootElement> 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!");
}
}

View File

@ -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<String> 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();
}