[New] Implemented locking for Strolch elements
Also cleaned up hierarchy of StrolchTransaction by moving up everything into AbstractTransaction as made sense and added special delegation methods for the actual commit() and rollback() ind the concrete implementations.
This commit is contained in:
parent
a7a4d4f5dd
commit
902a153043
|
@ -28,7 +28,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import li.strolch.agent.api.ComponentContainer;
|
import li.strolch.agent.api.ComponentContainer;
|
||||||
import li.strolch.agent.api.StrolchComponent;
|
import li.strolch.agent.api.StrolchComponent;
|
||||||
import li.strolch.agent.impl.StrolchRealm;
|
import li.strolch.agent.api.StrolchRealm;
|
||||||
import li.strolch.persistence.api.DbConnectionInfo;
|
import li.strolch.persistence.api.DbConnectionInfo;
|
||||||
import li.strolch.persistence.api.OrderDao;
|
import li.strolch.persistence.api.OrderDao;
|
||||||
import li.strolch.persistence.api.PersistenceHandler;
|
import li.strolch.persistence.api.PersistenceHandler;
|
||||||
|
|
|
@ -16,128 +16,40 @@
|
||||||
package li.strolch.persistence.postgresql;
|
package li.strolch.persistence.postgresql;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import li.strolch.agent.impl.StrolchRealm;
|
import li.strolch.agent.api.StrolchRealm;
|
||||||
import li.strolch.model.StrolchElement;
|
|
||||||
import li.strolch.persistence.api.AbstractTransaction;
|
import li.strolch.persistence.api.AbstractTransaction;
|
||||||
import li.strolch.persistence.api.ModificationResult;
|
|
||||||
import li.strolch.persistence.api.OrderDao;
|
import li.strolch.persistence.api.OrderDao;
|
||||||
import li.strolch.persistence.api.PersistenceHandler;
|
import li.strolch.persistence.api.PersistenceHandler;
|
||||||
import li.strolch.persistence.api.ResourceDao;
|
import li.strolch.persistence.api.ResourceDao;
|
||||||
import li.strolch.persistence.api.StrolchPersistenceException;
|
|
||||||
import li.strolch.persistence.api.TransactionCloseStrategy;
|
|
||||||
import li.strolch.persistence.api.TransactionResult;
|
import li.strolch.persistence.api.TransactionResult;
|
||||||
import li.strolch.persistence.api.TransactionState;
|
|
||||||
import li.strolch.runtime.observer.ObserverHandler;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import ch.eitchnet.utils.helper.StringHelper;
|
|
||||||
|
|
||||||
public class PostgreSqlStrolchTransaction extends AbstractTransaction {
|
public class PostgreSqlStrolchTransaction extends AbstractTransaction {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(PostgreSqlStrolchTransaction.class);
|
private static final Logger logger = LoggerFactory.getLogger(PostgreSqlStrolchTransaction.class);
|
||||||
private PostgreSqlPersistenceHandler persistenceHandler;
|
private PostgreSqlPersistenceHandler persistenceHandler;
|
||||||
|
|
||||||
private TransactionCloseStrategy closeStrategy;
|
|
||||||
private ObserverHandler observerHandler;
|
|
||||||
private boolean suppressUpdates;
|
|
||||||
|
|
||||||
private PostgresqlDao<?> orderDao;
|
private PostgresqlDao<?> orderDao;
|
||||||
private PostgresqlDao<?> resourceDao;
|
private PostgresqlDao<?> resourceDao;
|
||||||
private Connection connection;
|
private Connection connection;
|
||||||
private long startTime;
|
|
||||||
private Date startTimeDate;
|
|
||||||
private TransactionResult txResult;
|
|
||||||
private boolean open;
|
|
||||||
|
|
||||||
public PostgreSqlStrolchTransaction(StrolchRealm realm, PostgreSqlPersistenceHandler persistenceHandler) {
|
public PostgreSqlStrolchTransaction(StrolchRealm realm, PostgreSqlPersistenceHandler persistenceHandler) {
|
||||||
super(realm);
|
super(realm);
|
||||||
this.startTime = System.nanoTime();
|
|
||||||
this.startTimeDate = new Date();
|
|
||||||
this.persistenceHandler = persistenceHandler;
|
this.persistenceHandler = persistenceHandler;
|
||||||
this.suppressUpdates = false;
|
|
||||||
this.closeStrategy = TransactionCloseStrategy.COMMIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param observerHandler
|
|
||||||
* the observerHandler to set
|
|
||||||
*/
|
|
||||||
public void setObserverHandler(ObserverHandler observerHandler) {
|
|
||||||
this.observerHandler = observerHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param suppressUpdates
|
|
||||||
* the suppressUpdates to set
|
|
||||||
*/
|
|
||||||
public void setSuppressUpdates(boolean suppressUpdates) {
|
|
||||||
this.suppressUpdates = suppressUpdates;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the suppressUpdates
|
|
||||||
*/
|
|
||||||
public boolean isSuppressUpdates() {
|
|
||||||
return this.suppressUpdates;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCloseStrategy(TransactionCloseStrategy closeStrategy) {
|
protected void commit(TransactionResult txResult) throws Exception {
|
||||||
this.closeStrategy = closeStrategy;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void autoCloseableCommit() {
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.info("Committing TX for realm " + getRealmName() + "..."); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
long start = System.nanoTime();
|
|
||||||
this.txResult = new TransactionResult();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (this.orderDao != null)
|
if (this.orderDao != null)
|
||||||
this.orderDao.commit(this.txResult);
|
this.orderDao.commit(txResult);
|
||||||
if (this.resourceDao != null)
|
if (this.resourceDao != null)
|
||||||
this.resourceDao.commit(this.txResult);
|
this.resourceDao.commit(txResult);
|
||||||
if (this.connection != null)
|
if (this.connection != null)
|
||||||
this.connection.commit();
|
this.connection.commit();
|
||||||
|
|
||||||
this.txResult.setState(TransactionState.COMMITTED);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
if (this.connection != null) {
|
|
||||||
try {
|
|
||||||
this.connection.rollback();
|
|
||||||
} catch (SQLException e1) {
|
|
||||||
logger.error("Failed to rollback transation due to " + e.getMessage(), e); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.txResult.setState(TransactionState.FAILED);
|
|
||||||
long end = System.nanoTime();
|
|
||||||
long txDuration = end - this.startTime;
|
|
||||||
long closeDuration = end - start;
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("TX for realm ");
|
|
||||||
sb.append(getRealmName());
|
|
||||||
sb.append(" has failed after "); //$NON-NLS-1$
|
|
||||||
sb.append(StringHelper.formatNanoDuration(txDuration));
|
|
||||||
sb.append(" with close operation taking "); //$NON-NLS-1$
|
|
||||||
sb.append(StringHelper.formatNanoDuration(closeDuration));
|
|
||||||
logger.info(sb.toString());
|
|
||||||
|
|
||||||
throw new StrolchPersistenceException(
|
|
||||||
"Strolch Transaction for realm " + getRealmName() + " failed due to " + e.getMessage(), e); //$NON-NLS-1$
|
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
if (this.connection != null) {
|
if (this.connection != null) {
|
||||||
try {
|
try {
|
||||||
|
@ -147,47 +59,13 @@ public class PostgreSqlStrolchTransaction extends AbstractTransaction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long end = System.nanoTime();
|
|
||||||
long txDuration = end - this.startTime;
|
|
||||||
long closeDuration = end - start;
|
|
||||||
|
|
||||||
this.txResult.setStartTime(this.startTimeDate);
|
|
||||||
this.txResult.setTxDuration(txDuration);
|
|
||||||
this.txResult.setCloseDuration(closeDuration);
|
|
||||||
this.txResult.setRealm(getRealm().getRealm());
|
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("TX for realm ");
|
|
||||||
sb.append(getRealmName());
|
|
||||||
sb.append(" was completed after "); //$NON-NLS-1$
|
|
||||||
sb.append(StringHelper.formatNanoDuration(txDuration));
|
|
||||||
sb.append(" with close operation taking "); //$NON-NLS-1$
|
|
||||||
sb.append(StringHelper.formatNanoDuration(closeDuration));
|
|
||||||
logger.info(sb.toString());
|
|
||||||
|
|
||||||
if (!this.suppressUpdates && this.observerHandler != null) {
|
|
||||||
|
|
||||||
Set<String> keys = this.txResult.getKeys();
|
|
||||||
for (String key : keys) {
|
|
||||||
ModificationResult modificationResult = this.txResult.getModificationResult(key);
|
|
||||||
|
|
||||||
this.observerHandler.add(key, modificationResult.<StrolchElement> getCreated());
|
|
||||||
this.observerHandler.update(key, modificationResult.<StrolchElement> getUpdated());
|
|
||||||
this.observerHandler.remove(key, modificationResult.<StrolchElement> getDeleted());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void autoCloseableRollback() {
|
protected void rollback(TransactionResult txResult) throws Exception {
|
||||||
long start = System.nanoTime();
|
|
||||||
|
|
||||||
if (this.connection != null) {
|
if (this.connection != null) {
|
||||||
try {
|
try {
|
||||||
this.connection.rollback();
|
this.connection.rollback();
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new StrolchPersistenceException("Strolch Transaction failed due to " + e.getMessage(), e); //$NON-NLS-1$
|
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
this.connection.close();
|
this.connection.close();
|
||||||
|
@ -196,27 +74,6 @@ public class PostgreSqlStrolchTransaction extends AbstractTransaction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long end = System.nanoTime();
|
|
||||||
long txDuration = end - this.startTime;
|
|
||||||
long closeDuration = end - start;
|
|
||||||
|
|
||||||
this.txResult = new TransactionResult();
|
|
||||||
this.txResult.setState(TransactionState.ROLLED_BACK);
|
|
||||||
this.txResult.setStartTime(this.startTimeDate);
|
|
||||||
this.txResult.setTxDuration(txDuration);
|
|
||||||
this.txResult.setCloseDuration(closeDuration);
|
|
||||||
this.txResult.setRealm(getRealm().getRealm());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws StrolchPersistenceException {
|
|
||||||
this.closeStrategy.close(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isOpen() {
|
|
||||||
return this.open;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OrderDao getOrderDao() {
|
OrderDao getOrderDao() {
|
||||||
|
@ -231,9 +88,6 @@ public class PostgreSqlStrolchTransaction extends AbstractTransaction {
|
||||||
return (ResourceDao) this.resourceDao;
|
return (ResourceDao) this.resourceDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
Connection getConnection() {
|
Connection getConnection() {
|
||||||
if (this.connection == null) {
|
if (this.connection == null) {
|
||||||
this.connection = this.persistenceHandler.getConnection(getRealm().getRealm());
|
this.connection = this.persistenceHandler.getConnection(getRealm().getRealm());
|
||||||
|
|
|
@ -22,8 +22,8 @@ import static org.junit.Assert.assertNull;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import li.strolch.agent.api.StrolchRealm;
|
||||||
import li.strolch.agent.impl.DataStoreMode;
|
import li.strolch.agent.impl.DataStoreMode;
|
||||||
import li.strolch.agent.impl.StrolchRealm;
|
|
||||||
import li.strolch.model.ModelGenerator;
|
import li.strolch.model.ModelGenerator;
|
||||||
import li.strolch.model.Resource;
|
import li.strolch.model.Resource;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
|
|
Loading…
Reference in New Issue