Barrett Oglesby created GEODE-9122:
--------------------------------------

             Summary: Setting group-transaction-events=true can cause 
ConcurrentModificationExceptions
                 Key: GEODE-9122
                 URL: https://issues.apache.org/jira/browse/GEODE-9122
             Project: Geode
          Issue Type: Bug
          Components: wan
            Reporter: Barrett Oglesby


The 
SerialWANStatsDUnitTest.testReplicatedSerialPropagationHAWithGroupTransactionEvents
 test can throw a ConcurrentModificationException like:
{noformat}
[warn 2021/04/04 02:55:53.253 GMT  <Event Processor for GatewaySender_ln> 
tid=0x15d] An Exception occurred. The dispatcher will continue.
java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextNode(HashMap.java:1445)
        at java.util.HashMap$KeyIterator.next(HashMap.java:1469)
        at 
org.apache.geode.internal.cache.wan.serial.SerialGatewaySenderQueue.peekEventsFromIncompleteTransactions(SerialGatewaySenderQueue.java:476)
        at 
org.apache.geode.internal.cache.wan.serial.SerialGatewaySenderQueue.peek(SerialGatewaySenderQueue.java:453)
        at 
org.apache.geode.internal.cache.wan.AbstractGatewaySenderEventProcessor.processQueue(AbstractGatewaySenderEventProcessor.java:518)
        at 
org.apache.geode.internal.cache.wan.serial.SerialGatewaySenderEventProcessor.run(SerialGatewaySenderEventProcessor.java:223)
{noformat}
If the SerialGatewaySenderQueue.peekEventsFromIncompleteTransactions contains 
more than one TransactionId, and one of them is removed, the 
ConcurrentModificationException will occur.

Both the SerialGatewaySenderQueue and ParallelGatewaySenderQueue 
peekEventsFromIncompleteTransactions have the same implementation.

These methods do:
{noformat}
       while (true) {
1. ->    for (TransactionId transactionId : incompleteTransactionIdsInBatch) {
           ...
           if (...) {
              ...
2. ->         incompleteTransactionIdsInBatch.remove(transactionId);
           }
         }
       }
{noformat}
The for-each loop (1) cannot be paired with the remove from the 
incompleteTransactionIdsInBatch set (2). As soon as the remove is called, the 
ConcurrentModificationException will be thrown the next time through the loop. 
Since this for loop is in a while (true) loop, it is an infinite loop.

One way to address this would be to use an Iterator and call remove on the 
Iterator like:
{noformat}
1. ->    for (Iterator<TransactionId> i = 
incompleteTransactionIdsInBatch.iterator(); i.hasNext();) {
           TransactionId transactionId = i.next();
           ...
2. ->         i.remove();
{noformat}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to