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)