Implemented Rs/W transactions idea. See attached David's IRC monologue bellow for impl. details:

<dmlloyd> I wonder if maybe we should have read-only transactions too, for query operations
<dmlloyd> because those we can have many of at once
<dmlloyd> and we could use upgrade/downgrade operations as well

<dmlloyd> was thinking a little bit about a txn api to go with our discussion yesterday
<dmlloyd> if we had: interface ReadTransaction { ... }, interface UpdateTransaction extends ReadTransaction { ... }
<dmlloyd> we could confine each operation based upon whether it is update or read/update
<dmlloyd> then the transaction controller API would have methods like: void startReadTransaction(Listener<ReadTransaction> listener);
<dmlloyd> void startUpdateTransaction(Listener<UpdateTransaction> listener);
<dmlloyd> void downgradeTransaction(UpdateTransaction transaction, Listener<ReadTransaction> listener);
<dmlloyd> boolean upgradeTransaction(ReadTransaction transaction, Listener<UpdateTransaction> listener);
<dmlloyd> internally there could be some kind of queue
<dmlloyd> each item in the queue can be a single waiting updater, or a set of waiting readers
<dmlloyd> opening a read transaction -> if the queue is empty and the current txn is read, join readers, else look in queue:
          if tail of queue is a set of readers, join it, else add a new reader set to the end of the queue
<dmlloyd> opening a new update transaction -> if no transaction is active, open, else add a new updater to the end of the queue
<dmlloyd> downgrading -> invalidate current UpdateTransaction object, convert current update txn to read txn;
          if head of queue is a set of readers, dequeue allow all readers in the set to join the transaction; return new ReadTransaction
<dmlloyd> upgrading -> if queue is empty, add updater to queue with same txn object as the current reader & return true, else return false (cannot upgrade)
<dmlloyd> in the upgrading case the user could still use the same ReadTransaction object (it is harmless to do so)
<dmlloyd> in the downgrade case we probably don't want to do that since only the Update half of the interface will be invalidated
<dmlloyd> the downgrade method could return the ReadTransaction directly though instead of going through a listener, since there is never a wait to downgrade
<dmlloyd> also, downgrading should only be possible if no update actions have occurred