You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@geode.apache.org by "ASF subversion and git services (Jira)" <ji...@apache.org> on 2021/04/13 07:02:00 UTC

[jira] [Commented] (GEODE-9122) Setting group-transaction-events=true can cause ConcurrentModificationExceptions

    [ https://issues.apache.org/jira/browse/GEODE-9122?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17319965#comment-17319965 ] 

ASF subversion and git services commented on GEODE-9122:
--------------------------------------------------------

Commit 69834d5e81875850b1dde759d04a485f8b3aa461 in geode's branch refs/heads/develop from Alberto Gomez
[ https://gitbox.apache.org/repos/asf?p=geode.git;h=69834d5 ]

GEODE-9122: Avoid possible ConcurrentModificationException with group-transaction-events=true (#6278)

When group-transaction-events is set to true
if the SerialGatewaySenderQueue.peekEventsFromIncompleteTransactions
or ParallelGatewaySenderQueue.peekEventsFromIncompleteTransactions contain
more than one TransactionId, and one of them is removed,
the ConcurrentModificationException will occur.

> 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
>            Assignee: Alberto Gomez
>            Priority: Major
>              Labels: pull-request-available
>
> 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)