[jboss-svn-commits] JBL Code SVN: r29467 - in labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src: main/java/uk/ac/ncl/sdia/a8905943/impl and 9 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Fri Sep 25 06:41:24 EDT 2009
Author: whitingjr
Date: 2009-09-25 06:41:23 -0400 (Fri, 25 Sep 2009)
New Revision: 29467
Added:
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/field/AddIdentiyAction.java
Removed:
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/persistence/xa/JUnitTestSTMXAConnectionImpl.java
Modified:
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/entitymanager/STMEntityManagerImpl.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/impl/STMTransactionImpl.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/AbstractIsolation.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/Isolation.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/ReadCommittedIsolationImpl.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/ReadUncommittedIsolationImpl.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/RepeatableReadIsolationImpl.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/SerializableIsolationImpl.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/STM.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/object/TransactedObjectReference.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/transaction/STMTransaction.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/transaction/TransactionManager.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/entitymanager/TestSTMEntityManagerImpl.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/isolation/TestUnitRepeatableReadIsolationImpl.java
labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/stm/transaction/TestUnitTransactionManager.java
Log:
Added critical region to block reading of state during system update.
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/entitymanager/STMEntityManagerImpl.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/entitymanager/STMEntityManagerImpl.java 2009-09-25 10:38:07 UTC (rev 29466)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/entitymanager/STMEntityManagerImpl.java 2009-09-25 10:41:23 UTC (rev 29467)
@@ -7,7 +7,6 @@
package uk.ac.ncl.sdia.a8905943.entitymanager;
import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.SQLException;
@@ -35,9 +34,8 @@
import uk.ac.ncl.sdia.a8905943.handle.exception.FieldNotFoundException;
import uk.ac.ncl.sdia.a8905943.persistence.jdbc.STMConnection;
import uk.ac.ncl.sdia.a8905943.stm.activation.STMDisabled;
-import uk.ac.ncl.sdia.a8905943.stm.field.AddAction;
+import uk.ac.ncl.sdia.a8905943.stm.field.AddIdentiyAction;
import uk.ac.ncl.sdia.a8905943.stm.field.IdentityFieldWriteParameter;
-import uk.ac.ncl.sdia.a8905943.stm.field.RemoveAction;
import uk.ac.ncl.sdia.a8905943.stm.field.RemoveIdentityAction;
import uk.ac.ncl.sdia.a8905943.stm.query.STMQueryImpl;
import uk.ac.ncl.sdia.a8905943.stm.query.filter.Filter;
@@ -114,24 +112,32 @@
/* Check the field store for the identity field first, doing this detects if the entity has been removed beforehand. The model store*/
this.xpathContext.setLenient(true);
- StringBuffer query = new StringBuffer();
- query.append("model/").append(entityFQCN).append("[");
- query.append(idField.getName()).append("=$identityValue]");
- this.xpathContext.getVariables().declareVariable(IDENTITY_VALUE,
- entityUniqueIdentity);
+ StringBuffer queryString = new StringBuffer();
+ queryString.append("model/").append(entityFQCN).append("[");
+ queryString.append(idField.getName()).append("=$identityValue and stmf:notin(");
+ queryString.append(idField.getName()).append(")]");
+
+ Query query = this.createQuery(queryString.toString());
+ query.setParameter(IDENTITY_VALUE, entityUniqueIdentity);
+ query.setParameter("exclusionList", this.getSTMConnection().getSTM().getDeletedEntities(entity.getClass()));
if (logger.isTraceEnabled())
{
- logger.trace("executing query [" + query.toString() + "]");
+ logger.trace("executing query [" + queryString.toString() + "]");
}
- returnValue = (null == this.xpathContext.getValue(query.toString()) ? Boolean.FALSE
+ /*returnValue = (null == this.xpathContext.getValue(queryString.toString()) ? Boolean.FALSE
.booleanValue()
- : Boolean.TRUE.booleanValue());
- this.xpathContext.getVariables().undeclareVariable(IDENTITY_VALUE);
+ : Boolean.TRUE.booleanValue());*/
+ returnValue = (1 <= query.getResultList().size() ? Boolean.TRUE.booleanValue(): Boolean.FALSE.booleanValue() );
}
catch (FieldNotFoundException fnfe)
{
logger.error(fnfe.getMessage(), fnfe);
}
+ finally
+ {// undeclare the variable set to avoid affecting other queries
+ this.xpathContext.getVariables().undeclareVariable("exclusionList");
+ this.xpathContext.getVariables().undeclareVariable("identityValue");
+ }
}
return returnValue;
}
@@ -249,7 +255,6 @@
queryStatement.append("model/").append(entityClass.getName()).append(
"[").append(idField.getName());
queryStatement.append("=$identityValue and stmf:notin(").append(idField.getName()).append(")]");
- this.xpathContext.setFunctions(new ClassFunctions(NotInExtensionFunction.class, "stmf"));
Query query = this.createQuery(queryStatement.toString(), new NoOpFilter());
query.setParameter("identityValue", primaryKey);
query.setParameter("exclusionList", getSTMConnection().getSTM().getDeletedEntities(entityClass));
@@ -406,10 +411,10 @@
logger.error("Error occurred when invoking each write method on entity.", iae);
throw new RuntimeException("Problem occured accessing method to remove the field from field store. Potential cleanup operation required.");
}*/
- long fieldStoreHandle = new HandleUtils().getHandle(entity.getClass(), id, identityField.getName());
- IdentityFieldWriteParameter write = new IdentityFieldWriteParameter(fieldStoreHandle, id, id, entity.getClass(), new AddAction());
- this.getSTMConnection().getSTM().write(write);
}
+ long fieldStoreHandle = new HandleUtils().getHandle(entity.getClass(), id, identityField.getName());
+ IdentityFieldWriteParameter write = new IdentityFieldWriteParameter(fieldStoreHandle, id, id, entity.getClass(), new AddIdentiyAction());
+ this.getSTMConnection().getSTM().write(write);
}
else
{// add a new entity
@@ -436,7 +441,7 @@
public void remove(Object entity)
{
detectectClosedConnection();
- /* Nullify all the entity fields. identity is excluded */
+ /* Identity is removed. */
Object nullref =null;
FieldUtils fieldUtils = new FieldUtils();
/*
@@ -458,6 +463,7 @@
}
}
*/
+ //TODO:jrw deceide what will be done with orphaned entity fields. They require cleanup. Especially when concurrent transactions may be modifiying the entity removed in this transaction
try
{// Now nullify the identity field
Field identityField = fieldUtils.findIdField(entity.getClass());
@@ -487,6 +493,7 @@
this.connection = connection;
STMFactory.getFactoryInstance().allocate(getSTMConnection().getSTM());
this.xpathContext = JXPathContext.newContext(getSTMConnection().getSTM());
+ this.xpathContext.setFunctions(new ClassFunctions(NotInExtensionFunction.class, "stmf"));
}
public STMConnection getSTMConnection()
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/impl/STMTransactionImpl.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/impl/STMTransactionImpl.java 2009-09-25 10:38:07 UTC (rev 29466)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/impl/STMTransactionImpl.java 2009-09-25 10:41:23 UTC (rev 29467)
@@ -24,6 +24,7 @@
import uk.ac.ncl.sdia.a8905943.stm.model.LoadEntityParameter;
import uk.ac.ncl.sdia.a8905943.stm.object.TransactedObjectReference;
import uk.ac.ncl.sdia.a8905943.stm.transaction.STMTransaction;
+import uk.ac.ncl.sdia.a8905943.stm.transaction.TransactionManager;
/**
* The purpose of this object is to perform the transaction functionality.
@@ -55,22 +56,6 @@
private Isolation isolation;
-
- /**
- *
- * @deprecated
- */
- public void commit()
- {
- // make object versioned fields visible to all other transactions (depending on isolation)
- // make versioned collection objects fields visible to all other transactions (depending on isolation)
- // change status
- // notify all transactions committed, cleanup reader and writer traces.
- //this.status = Status.STATUS_COMMITTED;
- //releaseHeldLocks();
- //this.phaseTwoTerminated.countDown();
- }
-
@Override
public void startTransaction()
{
@@ -91,11 +76,11 @@
}
@Override
- public Object read(FieldReadParameter fieldRead)
+ public Object read(FieldReadParameter fieldRead, TransactionManager transactionManager)
{
fieldRead.setReads(this.deferredReads);
fieldRead.setWrites(this.deferredWrites);
- return this.isolation.read(fieldRead);
+ return this.isolation.read(fieldRead, transactionManager);
}
@Override
@@ -172,9 +157,9 @@
TransactedObjectReference lockedReference = (TransactedObjectReference)iterator.next();
try
{
- if (lockedReference.getPrepared().isHeldByCurrentThread())
+ if (lockedReference.getPrepared().isWriteLockedByCurrentThread())
{
- lockedReference.getPrepared().unlock();
+ lockedReference.getPrepared().writeLock().unlock();
}
}
catch (IllegalMonitorStateException imse)
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/AbstractIsolation.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/AbstractIsolation.java 2009-09-25 10:38:07 UTC (rev 29466)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/AbstractIsolation.java 2009-09-25 10:41:23 UTC (rev 29467)
@@ -1,6 +1,5 @@
package uk.ac.ncl.sdia.a8905943.isolation;
-import uk.ac.ncl.sdia.a8905943.stm.field.FieldReadParameter;
import uk.ac.ncl.sdia.a8905943.stm.field.FieldWriteParameter;
import uk.ac.ncl.sdia.a8905943.tracker.TransactionWriteSet;
@@ -20,13 +19,8 @@
{// default behaviour
return false;
}
+
@Override
- public Object read(FieldReadParameter fieldRead)
- {
- // FIXME read
- return null;
- }
- @Override
public Boolean write(FieldWriteParameter fieldWrite)
{
// FIXME write
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/Isolation.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/Isolation.java 2009-09-25 10:38:07 UTC (rev 29466)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/Isolation.java 2009-09-25 10:41:23 UTC (rev 29467)
@@ -1,7 +1,9 @@
package uk.ac.ncl.sdia.a8905943.isolation;
+
import uk.ac.ncl.sdia.a8905943.stm.field.FieldReadParameter;
import uk.ac.ncl.sdia.a8905943.stm.field.FieldWriteParameter;
+import uk.ac.ncl.sdia.a8905943.stm.transaction.TransactionManager;
@@ -11,7 +13,7 @@
public boolean supportsRepeatableRead();
public boolean supportsWriteSkew();
- public Object read(FieldReadParameter fieldRead);
+ public Object read(FieldReadParameter fieldRead, TransactionManager transManager);
/**
* Use this method to write a field object to the transaction.
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/ReadCommittedIsolationImpl.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/ReadCommittedIsolationImpl.java 2009-09-25 10:38:07 UTC (rev 29466)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/ReadCommittedIsolationImpl.java 2009-09-25 10:41:23 UTC (rev 29467)
@@ -1,9 +1,11 @@
package uk.ac.ncl.sdia.a8905943.isolation;
+import uk.ac.ncl.sdia.a8905943.stm.field.FieldReadParameter;
+import uk.ac.ncl.sdia.a8905943.stm.transaction.TransactionManager;
-public class ReadCommittedIsolationImpl extends AbstractIsolation{
-
+public class ReadCommittedIsolationImpl extends AbstractIsolation
+{
@Override
public boolean supportsRepeatableRead()
@@ -19,4 +21,12 @@
return false;
}
+ @Override
+ public Object read(FieldReadParameter fieldRead,
+ TransactionManager transManager)
+ {
+ // FIXME read
+ return null;
+ }
+
}
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/ReadUncommittedIsolationImpl.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/ReadUncommittedIsolationImpl.java 2009-09-25 10:38:07 UTC (rev 29466)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/ReadUncommittedIsolationImpl.java 2009-09-25 10:41:23 UTC (rev 29467)
@@ -6,7 +6,10 @@
*/
package uk.ac.ncl.sdia.a8905943.isolation;
+import uk.ac.ncl.sdia.a8905943.stm.field.FieldReadParameter;
+import uk.ac.ncl.sdia.a8905943.stm.transaction.TransactionManager;
+
public class ReadUncommittedIsolationImpl extends AbstractIsolation
{
@@ -26,4 +29,12 @@
return false;
}
+ @Override
+ public Object read(FieldReadParameter fieldRead,
+ TransactionManager transManager)
+ {
+ // FIXME read
+ return null;
+ }
+
}
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/RepeatableReadIsolationImpl.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/RepeatableReadIsolationImpl.java 2009-09-25 10:38:07 UTC (rev 29466)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/RepeatableReadIsolationImpl.java 2009-09-25 10:41:23 UTC (rev 29467)
@@ -1,12 +1,16 @@
package uk.ac.ncl.sdia.a8905943.isolation;
+import java.util.concurrent.CountDownLatch;
+
import org.apache.log4j.Logger;
+import uk.ac.ncl.sdia.a8905943.impl.STMTransactionImpl;
import uk.ac.ncl.sdia.a8905943.stm.field.AddAction;
import uk.ac.ncl.sdia.a8905943.stm.field.FieldReadParameter;
import uk.ac.ncl.sdia.a8905943.stm.field.FieldWriteParameter;
import uk.ac.ncl.sdia.a8905943.stm.field.ReplaceAction;
import uk.ac.ncl.sdia.a8905943.stm.object.TransactedObjectReference;
+import uk.ac.ncl.sdia.a8905943.stm.transaction.TransactionManager;
/**
* This object defines the behaviour for reads and writes for a
@@ -27,7 +31,7 @@
*
* @return
*/
- public Object read(FieldReadParameter fieldRead)
+ public Object read(FieldReadParameter fieldRead, TransactionManager transactionManager)
{
Object returnValue = null;
//
@@ -50,7 +54,38 @@
// retrieve from shared memory back to caller
if (fieldRead.getObjectStore().containsKey(fieldRead.getHandle()))
{
- returnValue = fieldRead.getObjectStore().get(fieldRead.getHandle() ).getValue();
+ /* Check to ensure the system update is not in progress */
+ // obtain latch and await completion of system update.
+ boolean unread = true;
+ while(unread)
+ {
+ if (0 == fieldRead.getObjectStore().get(fieldRead.getHandle()).getPrepared().getReadLockCount())
+ {// no lock
+ returnValue = fieldRead.getObjectStore().get(fieldRead.getHandle() ).getValue(); // this is insufficient, between this and the if a concurrent thread may have started updating.TODO:jrw how to detect/prevent this happening
+ unread = false;
+ }
+ else
+ {
+ STMTransactionImpl transaction = (STMTransactionImpl)transactionManager.findTransaction(fieldRead.getObjectStore().get(fieldRead.getHandle()).getVersion());
+ CountDownLatch latch = transaction.getPhaseTwoTerminated();
+ if (0 == latch.getCount())
+ {// problem here, indicates the concurrent transaction completed, but has not released all read locks on the shared resource.
+ logger.error("Problem occured when trying to read a field that was being updated. A concurrent transaction has not released all locks before completing commit.");
+ throw new RuntimeException("Lock release problem occured when reading a field.");
+ }
+ else
+ {
+ try
+ {
+ latch.await();
+ }
+ catch (InterruptedException ie)
+ {
+ logger.error("When waiting for a system update to complete updating.");
+ }
+ }
+ }
+ }
}
else
{
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/SerializableIsolationImpl.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/SerializableIsolationImpl.java 2009-09-25 10:38:07 UTC (rev 29466)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/isolation/SerializableIsolationImpl.java 2009-09-25 10:41:23 UTC (rev 29467)
@@ -1,6 +1,9 @@
package uk.ac.ncl.sdia.a8905943.isolation;
+import uk.ac.ncl.sdia.a8905943.stm.field.FieldReadParameter;
+import uk.ac.ncl.sdia.a8905943.stm.transaction.TransactionManager;
+
public class SerializableIsolationImpl extends AbstractIsolation {
@Override
@@ -17,4 +20,12 @@
return false;
}
+ @Override
+ public Object read(FieldReadParameter fieldRead,
+ TransactionManager transManager)
+ {
+ // FIXME read
+ return null;
+ }
+
}
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/STM.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/STM.java 2009-09-25 10:38:07 UTC (rev 29466)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/STM.java 2009-09-25 10:41:23 UTC (rev 29467)
@@ -66,7 +66,7 @@
fieldRead.setTransactional(this.trackingEnabled.get().booleanValue());
fieldRead.setObjectStore(this.transactedFieldMemory);
STMTransaction transaction = TransactionFactory.getFactory().getCurrentTransaction(false);
- return transaction.read(fieldRead);
+ return transaction.read(fieldRead, this.transactionManager);
}
public STM(String name, ConcurrentMap<Long, TransactedObjectReference> transactedFieldMemory, ConcurrentMap<String, List<Object>> transactedModelMemory)
Added: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/field/AddIdentiyAction.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/field/AddIdentiyAction.java (rev 0)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/field/AddIdentiyAction.java 2009-09-25 10:41:23 UTC (rev 29467)
@@ -0,0 +1,47 @@
+ /*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package uk.ac.ncl.sdia.a8905943.stm.field;
+
+import java.util.Set;
+
+public class AddIdentiyAction extends AddAction
+{
+
+ /**
+ * This method updates the Set containing the unique identity of each entity
+ */
+ @Override
+ public void execute(FieldWriteParameter parameter)
+ {
+ super.execute(parameter);
+ IdentityFieldWriteParameter identityParameter = (IdentityFieldWriteParameter )parameter;
+ if (identityParameter.getWrittenIdentityFields().containsKey(identityParameter.getType().getName()))
+ {
+ Set<Long> deletedIdentities = identityParameter.getWrittenIdentityFields().get(identityParameter.getType().getName());
+ if (deletedIdentities.contains(identityParameter.getIdentity()))
+ {// the entity has been deleted during this transaction, remove it from deleted collection
+ deletedIdentities.remove(identityParameter.getIdentity());
+ }
+ }
+ }
+}
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/object/TransactedObjectReference.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/object/TransactedObjectReference.java 2009-09-25 10:38:07 UTC (rev 29466)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/object/TransactedObjectReference.java 2009-09-25 10:41:23 UTC (rev 29467)
@@ -9,7 +9,7 @@
import java.io.Serializable;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
-import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.commons.lang.builder.EqualsBuilder;
@@ -20,7 +20,7 @@
final Long lookupIdentity;
protected AtomicReference<Object> value = new AtomicReference<Object>();
protected AtomicLong version = new AtomicLong();
- transient final ReentrantLock prepared = new ReentrantLock(true);
+ transient final ReentrantReadWriteLock prepared = new ReentrantReadWriteLock(true);
protected transient Long preparedVersion ;
private Updater updater;
@@ -74,7 +74,7 @@
return returnValue;
}
- public ReentrantLock getPrepared()
+ public ReentrantReadWriteLock getPrepared()
{
return prepared;
}
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/transaction/STMTransaction.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/transaction/STMTransaction.java 2009-09-25 10:38:07 UTC (rev 29466)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/transaction/STMTransaction.java 2009-09-25 10:41:23 UTC (rev 29467)
@@ -28,7 +28,7 @@
{
public int getStatus();
public Boolean write(FieldWriteParameter fieldWrite);
- public Object read(FieldReadParameter fieldRead);
+ public Object read(FieldReadParameter fieldRead, TransactionManager transManager);
public void setIsolationLevel(Isolation isolation);
public void startTransaction();
public Object load(LoadEntityParameter load);
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/transaction/TransactionManager.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/transaction/TransactionManager.java 2009-09-25 10:38:07 UTC (rev 29466)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/main/java/uk/ac/ncl/sdia/a8905943/stm/transaction/TransactionManager.java 2009-09-25 10:41:23 UTC (rev 29467)
@@ -42,7 +42,6 @@
return returnValue;
}
-
/**
* The purpose of this validate is to check all the fields in the transaction object
* for reads that are now stale.
@@ -87,17 +86,15 @@
TransactedObjectReference sharedReference = fieldMemory.get(reference.getLookupIdentity());
if (null != sharedReference)
{
- if (sharedReference.getPrepared().isHeldByCurrentThread())
+ if (sharedReference.getPrepared().isWriteLockedByCurrentThread())
{
sharedReference.setPreparedVersion(null);
- //sharedReference.notifyAll();
- sharedReference.getPrepared().unlock();
+ sharedReference.getPrepared().writeLock().unlock();
}
else
{
logger.error("Problem occured, prepared lock is not held by current thread. Interleaving threads not working properly.");
}
-
}
}
catch (Exception e)
@@ -148,7 +145,7 @@
{// loop through the write list, attempt lock and validate
// try and get the lock
TransactedObjectReference sharedField = prepareParameter.getFieldMemory().get(write.getLookupIdentity());
- boolean locked = sharedField.getPrepared().tryLock();
+ boolean locked = sharedField.getPrepared().writeLock().tryLock();
if (locked)
{
/* Invariant alert: small window between lock acquisition and setting of prepared version. TODO: refactor*/
@@ -201,12 +198,16 @@
{
try
{
- if (locked.getPrepared().isHeldByCurrentThread())
+ if (locked.getPrepared().writeLock().isHeldByCurrentThread())
{// small window here when this thread is barged from the lock
locked.setPreparedVersion(null);
- locked.getPrepared().notifyAll();
- locked.getPrepared().unlock();
+ locked.getPrepared().writeLock().notifyAll();
+ locked.getPrepared().writeLock().unlock();
}
+ if (0 < locked.getPrepared().getReadHoldCount())
+ {
+ locked.getPrepared().readLock().unlock();
+ }
}
catch (IllegalMonitorStateException imse)
{
@@ -258,6 +259,8 @@
/**
* Make all the changes to the shared version of system state.
+ * Before making the changes is to introduce a critical region to exclude other transactions from
+ * reading any of the resources that are being changed. This ensures changes appear atomically.
*
* @param transaction
* @param fieldMemory
@@ -266,45 +269,77 @@
public boolean commit(STMTransaction transaction, ConcurrentMap<Long, TransactedObjectReference> fieldMemory)
{
boolean returnValue = false;
- boolean isValid = true;
+ boolean isReadLockValid = true;
+
// loop through all the writes and swap them for the current value.
Collection<TransactedObjectReference> collection = transaction.getDeferredWrites().values();
+
+ /* Before updating each value lock each field. To prevent concurrent transactions reading inconsistent state. */
for (TransactedObjectReference deferredWrite : collection)
- {// replace the values, retain the prepared lock
- // quick validation nothing has been modified. should not happen because locks have been acquired.
+ {
TransactedObjectReference sharedReference = fieldMemory.get(deferredWrite.getLookupIdentity());
- if (isStale( transaction.getDeferredReads().get( deferredWrite.getLookupIdentity()),sharedReference))
+ if (!sharedReference.getPrepared().readLock().tryLock())
{
- logger.error("STM TransactionManager has detected a validation error during commit. A field is stale. ["+deferredWrite.toString()+"]");
- isValid = false;
+ logger.error("Synchronization problem occured when excluding transactions from reading state. During commit failed to read lock field.");
+ isReadLockValid = false;
break;
}
- /* don't really want to substitute the shared version with the deferred write.
- * should update values and use the count down latch to notify resource available. */
- // go ahead and replace all the values inside the shared transacted reference.
-
- //TODO: jrw refactor the update mechanism. Needs to be architected to support complex update mechanisms such as modifying the model store as well as removing something from field store.
- sharedReference.setValue(deferredWrite.getValue());
- sharedReference.setVersion(deferredWrite.getVersion());
- sharedReference.setPreparedVersion(null);
}
- if (isValid)
+ if (isReadLockValid)
{
+ boolean isWriteValid = true;
for (TransactedObjectReference deferredWrite : collection)
+ {// replace the values, retain the prepared lock
+ // quick validation nothing has been modified. should not happen because locks have been acquired.
+ TransactedObjectReference sharedReference = fieldMemory.get(deferredWrite.getLookupIdentity());
+ if (isStale( transaction.getDeferredReads().get( deferredWrite.getLookupIdentity()),sharedReference))
+ {
+ logger.error("STM TransactionManager has detected a validation problem during commit. A field is stale. ["+deferredWrite.toString()+"]");
+ isWriteValid = false;
+ break;
+ }
+ /* don't really want to substitute the shared version with the deferred write.
+ * should update values and use the count down latch to notify resource available. */
+ // go ahead and replace all the values inside the shared transacted reference.
+
+ //TODO: jrw refactor the update mechanism. Needs to be architected to support complex update mechanisms such as modifying the model store as well as removing something from field store.
+ sharedReference.setValue(deferredWrite.getValue());
+ sharedReference.setVersion(deferredWrite.getVersion());
+ sharedReference.setPreparedVersion(null);
+ }
+ if (isWriteValid)
+ {
+ for (TransactedObjectReference deferredWrite : collection)
+ {// release the locks
+ TransactedObjectReference sharedReference = fieldMemory.get(deferredWrite.getLookupIdentity());
+ if (sharedReference.getPrepared().writeLock().isHeldByCurrentThread())
+ {
+ sharedReference.getPrepared().writeLock().unlock();
+ }
+ if (0 < sharedReference.getPrepared().getReadHoldCount())
+ {
+ sharedReference.getPrepared().readLock().unlock();
+ }
+ }
+ transaction.getPhaseTwoTerminated().countDown();
+ returnValue = true;
+ }
+ }
+ else
+ {
+ for (TransactedObjectReference deferredWrite : collection)
{// release the locks
TransactedObjectReference sharedReference = fieldMemory.get(deferredWrite.getLookupIdentity());
- if (sharedReference.getPrepared().isHeldByCurrentThread())
+ if (0 < sharedReference.getPrepared().getReadHoldCount())
{
- sharedReference.getPrepared().unlock();
+ sharedReference.getPrepared().readLock().unlock();
}
}
- transaction.getPhaseTwoTerminated().countDown();
- returnValue = true;
}
+
return returnValue;
}
-
private boolean isExpired(long expiryTime)
{
return expiryTime > System.currentTimeMillis();
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/entitymanager/TestSTMEntityManagerImpl.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/entitymanager/TestSTMEntityManagerImpl.java 2009-09-25 10:38:07 UTC (rev 29466)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/entitymanager/TestSTMEntityManagerImpl.java 2009-09-25 10:41:23 UTC (rev 29467)
@@ -197,6 +197,7 @@
LeccyCar secondAttemptAfterRemoval = this.entityManager.find(LeccyCar.class, carId);
Assert.assertNull(secondAttemptAfterRemoval);
}
+
@Test
public void testCheckFindingDeletedAfterAdding()
{
@@ -216,9 +217,11 @@
Assert.assertNotNull(foundEntity.getId());
Assert.assertEquals(foundEntity.getId(), carId );
this.entityManager.remove(foundEntity);
- LeccyCar secondAttemptAfterRemoval = this.entityManager.find(LeccyCar.class, carId);
- Assert.assertNull(secondAttemptAfterRemoval);
+ Assert.assertFalse(this.entityManager.contains(car));
+ this.entityManager.persist(car);
+ Assert.assertTrue(this.entityManager.contains(car));
+ Assert.assertNotNull(this.entityManager.find(LeccyCar.class, carId));
}
@Override
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/isolation/TestUnitRepeatableReadIsolationImpl.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/isolation/TestUnitRepeatableReadIsolationImpl.java 2009-09-25 10:38:07 UTC (rev 29466)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/isolation/TestUnitRepeatableReadIsolationImpl.java 2009-09-25 10:41:23 UTC (rev 29467)
@@ -6,6 +6,8 @@
*/
package uk.ac.ncl.sdia.a8905943.isolation;
+import java.util.concurrent.Executor;
+
import junit.framework.Assert;
import org.junit.Test;
@@ -14,6 +16,7 @@
import uk.ac.ncl.sdia.a8905943.handle.HandleUtils;
import uk.ac.ncl.sdia.a8905943.impl.STMTransactionImpl;
import uk.ac.ncl.sdia.a8905943.model.Car;
+import uk.ac.ncl.sdia.a8905943.model.LeccyCar;
import uk.ac.ncl.sdia.a8905943.stm.AbstractUnitT;
import uk.ac.ncl.sdia.a8905943.stm.field.FieldReadParameter;
import uk.ac.ncl.sdia.a8905943.stm.object.TransactedObjectReference;
Deleted: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/persistence/xa/JUnitTestSTMXAConnectionImpl.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/persistence/xa/JUnitTestSTMXAConnectionImpl.java 2009-09-25 10:38:07 UTC (rev 29466)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/persistence/xa/JUnitTestSTMXAConnectionImpl.java 2009-09-25 10:41:23 UTC (rev 29467)
@@ -1,12 +0,0 @@
-/*
- * JBoss, the OpenSource J2EE webOS
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package uk.ac.ncl.sdia.a8905943.persistence.xa;
-
-public class JUnitTestSTMXAConnectionImpl
-{
-
-}
Modified: labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/stm/transaction/TestUnitTransactionManager.java
===================================================================
--- labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/stm/transaction/TestUnitTransactionManager.java 2009-09-25 10:38:07 UTC (rev 29466)
+++ labs/jbosstm/workspace/whitingjr/trunk/MVCCSampleSTM/src/test/java/uk/ac/ncl/sdia/a8905943/stm/transaction/TestUnitTransactionManager.java 2009-09-25 10:41:23 UTC (rev 29467)
@@ -103,7 +103,7 @@
Assert.assertTrue(this.stm.prepare());
Assert.assertNotNull(reference.getPrepared());
- Assert.assertTrue(reference.getPrepared().isLocked()); // only one resource locked during prepare
+ Assert.assertTrue(reference.getPrepared().isWriteLocked()); // only one resource locked during prepare
Assert.assertEquals(Status.STATUS_PREPARED, transaction.getStatus());
}
@@ -137,13 +137,13 @@
{
}
- Assert.assertTrue(reference.getPrepared().isLocked());
+ Assert.assertTrue(reference.getPrepared().isWriteLocked());
Assert.assertEquals(1, transaction.getDeferredReads().size());
Assert.assertEquals( 1, this.fieldStore.size());
Assert.assertFalse(this.stm.prepare());
- Assert.assertFalse(reference.getPrepared().isHeldByCurrentThread()); // only one resource locked during prepare
+ Assert.assertFalse(reference.getPrepared().writeLock().isHeldByCurrentThread()); // only one resource locked during prepare
Assert.assertEquals(Status.STATUS_MARKED_ROLLBACK, transaction.getStatus());
}
@@ -193,7 +193,7 @@
Assert.assertTrue(this.stm.prepare());
Assert.assertNotNull(reference.getPrepared());
- Assert.assertTrue(reference.getPrepared().isLocked()); // only one resource locked during prepare
+ Assert.assertTrue(reference.getPrepared().isWriteLocked()); // only one resource locked during prepare
Assert.assertEquals(Status.STATUS_PREPARED, transaction.getStatus());
Assert.assertTrue(this.stm.commit());
Assert.assertEquals(buyOutMake, reference.getValue());
@@ -237,7 +237,7 @@
car.setMake("Fiat");
Assert.assertEquals(1, this.stm.getFieldStore().size());
TransactedObjectReference reference = this.stm.getFieldStore().get(handle);
- reference.getPrepared().lock();// that's it locked, job done
+ reference.getPrepared().writeLock().lock();// that's it locked, job done
reference.setPreparedVersion(transaction.getVersion());
this.latch.countDown();
}
More information about the jboss-svn-commits
mailing list