You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by jo...@apache.org on 2006/02/03 23:25:14 UTC

svn commit: r374764 - in /jakarta/commons/proper/transaction/trunk: RELEASE-NOTES.txt src/java/org/apache/commons/transaction/memory/OptimisticMapWrapper.java

Author: joerg
Date: Fri Feb  3 14:25:08 2006
New Revision: 374764

URL: http://svn.apache.org/viewcvs?rev=374764&view=rev
Log:
Fixed bugzilla issue 35377. Synchronizing on Set activeTransactions while iterating over its items in OptimisticMapWrapper.copyChangesToConcurrentTransactions() for preventing ConcurrentModificationException.
Thanks to John Rousseau.

Modified:
    jakarta/commons/proper/transaction/trunk/RELEASE-NOTES.txt
    jakarta/commons/proper/transaction/trunk/src/java/org/apache/commons/transaction/memory/OptimisticMapWrapper.java

Modified: jakarta/commons/proper/transaction/trunk/RELEASE-NOTES.txt
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/transaction/trunk/RELEASE-NOTES.txt?rev=374764&r1=374763&r2=374764&view=diff
==============================================================================
--- jakarta/commons/proper/transaction/trunk/RELEASE-NOTES.txt (original)
+++ jakarta/commons/proper/transaction/trunk/RELEASE-NOTES.txt Fri Feb  3 14:25:08 2006
@@ -31,6 +31,8 @@
 - Fixed bug reported by Niklas Gustavsson on http://www.mail-archive.com/commons-dev@jakarta.apache.org/msg69441.html.
   Failed deletion of a file now throws an exception and enters an error state upon commit.
 - Reduced likelyhood of clash between internally generated and external tx id in generatedUniqueTxId
+- Fixed bugzilla issue 35377. Synchronizing on Set activeTransactions while iterating over its items in
+  OptimisticMapWrapper.copyChangesToConcurrentTransactions() for preventing ConcurrentModificationException.
 
 KNOWN ISSUES
 ------------

Modified: jakarta/commons/proper/transaction/trunk/src/java/org/apache/commons/transaction/memory/OptimisticMapWrapper.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/transaction/trunk/src/java/org/apache/commons/transaction/memory/OptimisticMapWrapper.java?rev=374764&r1=374763&r2=374764&view=diff
==============================================================================
--- jakarta/commons/proper/transaction/trunk/src/java/org/apache/commons/transaction/memory/OptimisticMapWrapper.java (original)
+++ jakarta/commons/proper/transaction/trunk/src/java/org/apache/commons/transaction/memory/OptimisticMapWrapper.java Fri Feb  3 14:25:08 2006
@@ -63,9 +63,9 @@
     protected Set activeTransactions;
 
     protected LoggerFacade logger;
-    
+
     protected ReadWriteLock commitLock;
-    
+
     /**
      * Creates a new optimistic transactional map wrapper. Temporary maps and sets to store transactional
      * data will be instances of {@link java.util.HashMap} and {@link java.util.HashSet}. 
@@ -105,8 +105,7 @@
         this.logger = logger;
         commitLock = new ReadWriteLock("COMMIT", logger);
     }
-    
-    
+
     public void startTransaction() {
         if (getActiveTx() != null) {
             throw new IllegalStateException(
@@ -182,40 +181,40 @@
     protected void copyChangesToConcurrentTransactions() {
         CopyingTxContext thisTxContext = (CopyingTxContext) getActiveTx();
 
-        for (Iterator it = activeTransactions.iterator(); it.hasNext();) {
-            CopyingTxContext otherTxContext = (CopyingTxContext) it.next();
-
-            // no need to copy data if the other transaction does not access global map anyway
-            if (otherTxContext.cleared)
-                continue;
-
-            if (thisTxContext.cleared) {
-                // we will clear everything, so we have to copy everything before
-                otherTxContext.externalChanges.putAll(wrapped);
-            } else // no need to check if we have already copied everthing
+        synchronized (activeTransactions) {
+            for (Iterator it = activeTransactions.iterator(); it.hasNext();) {
+                CopyingTxContext otherTxContext = (CopyingTxContext) it.next();
+
+                // no need to copy data if the other transaction does not access global map anyway
+                if (otherTxContext.cleared)
+                    continue;
+
+                if (thisTxContext.cleared) {
+                    // we will clear everything, so we have to copy everything before
+                    otherTxContext.externalChanges.putAll(wrapped);
+                } else // no need to check if we have already copied everthing
                 {
-
-                for (Iterator it2 = thisTxContext.changes.entrySet().iterator(); it2.hasNext();) {
-                    Map.Entry entry = (Map.Entry) it2.next();
-                    Object value = wrapped.get(entry.getKey());
-                    if (value != null) {
-                        // undo change
-                        otherTxContext.externalChanges.put(entry.getKey(), value);
-                    } else {
-                        // undo add
-                        otherTxContext.externalDeletes.add(entry.getKey());
+                    for (Iterator it2 = thisTxContext.changes.entrySet().iterator(); it2.hasNext();) {
+                        Map.Entry entry = (Map.Entry) it2.next();
+                        Object value = wrapped.get(entry.getKey());
+                        if (value != null) {
+                            // undo change
+                            otherTxContext.externalChanges.put(entry.getKey(), value);
+                        } else {
+                            // undo add
+                            otherTxContext.externalDeletes.add(entry.getKey());
+                        }
                     }
-                }
 
-                for (Iterator it2 = thisTxContext.deletes.iterator(); it2.hasNext();) {
-                    // undo delete
-                    Object key = it2.next();
-                    Object value = wrapped.get(key);
-                    otherTxContext.externalChanges.put(key, value);
+                    for (Iterator it2 = thisTxContext.deletes.iterator(); it2.hasNext();) {
+                        // undo delete
+                        Object key = it2.next();
+                        Object value = wrapped.get(key);
+                        otherTxContext.externalChanges.put(key, value);
+                    }
                 }
             }
         }
-
     }
 
     public class CopyingTxContext extends TxContext {
@@ -316,7 +315,7 @@
                 commitLock.release(this);
             }
         }
-        
+
         protected void remove(Object key) {
             try {
                 commitLock.acquireRead(this, ACCESS_TIMEOUT);
@@ -365,7 +364,7 @@
                 commitLock.release(this);
             }
         }
-        
+
         protected void dispose() {
             try {
                 commitLock.acquireRead(this, ACCESS_TIMEOUT);



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org