[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