[
https://issues.apache.org/jira/browse/QPID-2900?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12991350#comment-12991350
]
Keith Wall commented on QPID-2900:
----------------------------------
I've traced the problem down to a race condition - broker side - within
SimpleAMQQueue.
The nub of the problem is the update of the atomic QueueContext._releasedEntry.
There is a circumstance where _releasedEntry is overwritten prematurely and
therefore the broker fails to resend the message to the client.
Here's how it happens:
In the cases where the tests fail, the thread (SubFlushRunner or QueueRunner)
executing SimpleAMQQueue.deliverMessage() is yielded part way through the
method. The thread has successfully sent the message to the client
(MESSAGE_TRANSFER etc), but the JVM yields the thread before it reaches
setLastSeen(). (SetLastSeen is responsible for advancing the lastSeen pointer,
and resetting _releasedEntry if necessary).
Meanwhile, the client receives the message, calls JMS rollback, which causes
MESSASE_RELEASE (etc) command to be sent to the broker, before it calls JMS
receive(). The broker processes the MESSAGE_RELEASE by invoking
SimpleAMQ.requeue() which in turn invokes updateSubRequeueEntry() to update
_releaseEntry with the QueueEntry to be resent.
Now, the JVM wakes-up the thread (SubFlushRunner or QueueRunner) that was part
way through processing SimpleAMQQueue .deliverMessage() for the initial send of
the message. The setLastSeen() method is invoked, which ***incorrectly***
resets _releasedEntry to null because _releaseEntry now is the same as the
entry being processed. The broker goes around the loop, calls
getNextAvailableEntry which returns null because _releaseEntry has been
prematurely cleared.
I've illustrated the success and failure cases as sequence diagrams (attached
to this JIRA).
> CommitRollbackTest#testGetThenRollback and
> CommitRollbackTest#testSend2ThenRollback fail on java.0.10 profile
> -------------------------------------------------------------------------------------------------------------
>
> Key: QPID-2900
> URL: https://issues.apache.org/jira/browse/QPID-2900
> Project: Qpid
> Issue Type: Bug
> Components: Java Broker, Java Client
> Reporter: Robbie Gemmell
> Assignee: Keith Wall
> Priority: Critical
> Fix For: 0.9
>
>
> org.apache.qpid.test.unit.transacted.CommitRollbackTest#testGetThenRollback
> org.apache.qpid.test.unit.transacted.CommitRollbackTest#testSend2ThenRollback
> These two tests fail very regularly (but not always) on the java.0.10 test
> profile:
> TestName: testGetThenRollback Duration: 6.882
> test message was consumed and rolled back,
> but is gone
> junit.framework.AssertionFailedError: test
> message was consumed and rolled back, but is gone
> at
> org.apache.qpid.test.unit.transacted.CommitRollbackTest.testGetThenRollback(CommitRollbackTest.java:273)
> at
> org.apache.qpid.test.utils.QpidBrokerTestCase.runBare(QpidBrokerTestCase.java:232)
> at org.apache.qpid.test.utils.QpidTestCase.run(QpidTestCase.java:120)
>
> TestName: testSend2ThenRollback Duration: 6.879
> Didn't receive redelivered message one
>
> junit.framework.AssertionFailedError: Didn't
> receive redelivered message one
> at
> org.apache.qpid.test.unit.transacted.CommitRollbackTest.verifyMessages(CommitRollbackTest.java:379)
> at
> org.apache.qpid.test.unit.transacted.CommitRollbackTest.verifyMessages(CommitRollbackTest.java:415)
> at
> org.apache.qpid.test.unit.transacted.CommitRollbackTest.testSend2ThenRollback(CommitRollbackTest.java:357)
> at
> org.apache.qpid.test.utils.QpidBrokerTestCase.runBare(QpidBrokerTestCase.java:232)
> at org.apache.qpid.test.utils.QpidTestCase.run(QpidTestCase.java:120)
>
--
This message is automatically generated by JIRA.
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project: http://qpid.apache.org
Use/Interact: mailto:[email protected]