[rabbitmq-discuss] Ordering of messages after txRollback()
Matthew Sackman
matthew at rabbitmq.com
Sun Jun 6 19:25:42 BST 2010
On Sun, Jun 06, 2010 at 11:05:49AM -0700, Oleg Zhurakousky wrote:
> Let me get this straight. TX are only for publishers, not consumers,
Not necessarily. A consumer, within a channel, can make the ack to one
message and the publish of another message atomic by using a
transaction. That's a pretty common use case for clients which do
transformations of messages.
> thus the only way to implement TX behavior on the consumer side is by not sending ACK. Is that correct?
The server remembers messages until they have been acked. Whilst the
channel to which a message was delivered stays up, the server waits for
the client to ack the message and will not deliver the message to
another client in the meantime (in the absence of
basic.recover{requeue=true}). When the channel closes, or the connection
dies, or the client specifically requeues requeuing of messages, the
unacknowledged messages get reinserted into the queue. You can sort of
think of that as a rollback.
> Since the spec is "completely silent" on the 'ordering',
You're always welcome to read the spec btw, it does contain many
answers...
> does that mean that when I retrieve messages initially and they come in order it is just a coincidence?
> I was under the impression that Queue semantics imply FIFO ordering, regardless of which spec implements such Queue. Am I missing something?
The spec specifies ordering with messages from one channel of a producer
going to one channel of a consumer. You're guaranteed FIFO semantics
there. But when not acking messages, requesting requeues, dealing with
multiple producers, consumers, transactions and rollbacks in the middle,
most bets are off. Rabbit does a best effort. Messages from the same
producer will hit the queue in order, when initially published.
But let's say you have 2 consumers off the same queue, and they're round
robining. The stream of messages into the queue is α β γ δ ε ζ. The first
consumer will get α γ ε, and the second β δ ζ. The queue is now empty.
The first consumer now dies, so even if we "maintained order", the queue
would now look like α γ ε. Now the second consumer dies, and the queue
now looks like α γ ε β δ ζ. So we now have messages in the queue in a
different order from being published, but we could claim we've
"maintained order". What are you going to do - reshuffle them to get
back to α β γ δ ε ζ? What happens if another consumer's already appeared
and consumed (and acked) α and γ - what are you going to do to β? -
silently drop it? Thus in the event of any requeue operations, whether
explicit or implicit, all bets are off on subsequent ordering of
requeued messages, because even if we tried as hard as possible to
maintain ordering, it would still be unavoidably observably wrong, in
comparison to the published ordering.
Matthew
More information about the rabbitmq-discuss
mailing list