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