summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Sackman <matthew@rabbitmq.com>2011-04-08 11:15:57 +0100
committerMatthew Sackman <matthew@rabbitmq.com>2011-04-08 11:15:57 +0100
commit08bab86f1c758eea61cefc5a81242c3e52ec818d (patch)
tree7ad7d039ab1f55b29d9934c475f4473024a29449
parent79bbb0a7c29bb4edbcc316c3bb993bca78d2aaf2 (diff)
downloadrabbitmq-server-git-08bab86f1c758eea61cefc5a81242c3e52ec818d.tar.gz
some notes
-rw-r--r--src/rabbit_mirror_queue_master.erl40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/rabbit_mirror_queue_master.erl b/src/rabbit_mirror_queue_master.erl
index 387dfbc481..664c706d33 100644
--- a/src/rabbit_mirror_queue_master.erl
+++ b/src/rabbit_mirror_queue_master.erl
@@ -42,6 +42,46 @@
ack_msg_id
}).
+%% Some notes on transactions
+%%
+%% We don't support transactions on mirror queues. To do so is
+%% challenging. The underlying bq is free to add the contents of the
+%% txn to the queue proper at any point after the tx.commit comes in
+%% but before the tx.commit-ok goes out. This means that it is not
+%% safe for all mirrors to simply issue the BQ:tx_commit at the same
+%% time, as the addition of the txn's contents to the queue may
+%% subsequently be inconsistently interwoven with other actions on the
+%% BQ. The solution to this is, in the master, wrap the PostCommitFun
+%% and do the gm:broadcast in there: at that point, you're in the BQ
+%% (well, there's actually nothing to stop that function being invoked
+%% by some other process, but let's pretend for now: you could always
+%% use run_backing_queue_async to ensure you really are in the queue
+%% process), the gm:broadcast is safe because you don't have to worry
+%% about races with other gm:broadcast calls (same process). Thus this
+%% signal would indicate sufficiently to all the slaves that they must
+%% insert the complete contents of the txn at precisely this point in
+%% the stream of events.
+%%
+%% However, it's quite difficult for the slaves to make that happen:
+%% they would be forced to issue the tx_commit at that point, but then
+%% stall processing any further instructions from gm until they
+%% receive the notification from their bq that the tx_commit has fully
+%% completed (i.e. they need to treat what is an async system as being
+%% fully synchronous). This is not too bad (apart from the
+%% vomit-inducing notion of it all): just need a queue of instructions
+%% from the GM; but then it gets rather worse when you consider what
+%% needs to happen if the master dies at this point and the slave in
+%% the middle of this tx_commit needs to be promoted.
+%%
+%% Finally, we can't possibly hope to make transactions atomic across
+%% mirror queues, and it's not even clear that that's desirable: if a
+%% slave fails whilst there's an open transaction in progress then
+%% when the channel comes to commit the txn, it will detect the
+%% failure and destroy the channel. However, the txn will have
+%% actually committed successfully in all the other mirrors (including
+%% master). To do this bit properly would require 2PC and all the
+%% baggage that goes with that.
+
%% ---------------------------------------------------------------------------
%% Backing queue
%% ---------------------------------------------------------------------------