c# - Snapshot isolation for reliable queue is broken? -
update: bug fixed in service fabric sdk version 2.4.164 on february 3, 2017. quote release notes:
fix reliablequeue correctly handle additional transaction levels , combinations
fixing bug reliablequeue.getcountasync did not adhere snapshot isolation if doing read own write. issue reported on stack overflow. thank bug reports.
i'm in process of writing mocks service fabric reliable collections. need these mocks mimic transactional behavior of real implementation close possible.
i have therefore written couple of test cases run verify mocks behave real implementation.
however, in test cases dealing snapshot isolation discovered mocks have different behavior. after looking closer i'm not sure fault on side.
so think may have stumbled on bug in how reliable queue enforce snapshot isolation.
the msdn docs snapshot isolation says:
the transaction can recognize data modifications committed before start of transaction. data modifications made other transactions after start of current transaction not visible statements executing in current transaction.
and:
reliable queue support read writes. in other words, write within transaction visible following read belongs same transaction.
so, operation mandate snapshot isolation, getcountasync
, should see consistent snapshot unaffected other transactions. changes made transaction owns snapshot shall visible.
this indeed case reliable dictionaries, not reliable queues.
snapshots taken reliable queue (by doing getcountasync
or createenumerableasync
) indeed unaffected modifications made other transactions if don't make changes ourselves. doing not make our own changes visible in snapshot expose changes other transactions.
the following snippet can dropped reliable service reproduce this:
public async task verify_that_reliable_queue_snapshot_isolation_is_broken() { // empty reliable queue var name = guid.newguid().tostring(); var queue = await this.statemanager.getoraddasync<ireliablequeue<string>>(name); // start transaction , take snapshot getting queue count var t1 = this.statemanager.createtransaction(); assert.areequal(0, await queue.getcountasync(t1)); // ok // enqueue in concurrent transaction using (var t2 = this.statemanager.createtransaction()) { await queue.enqueueasync(t2, "something"); await t2.commitasync(); } // snapshot should still 0 assert.areequal(0, await queue.getcountasync(t1)); // ok // enqueue else in first transaction await queue.enqueueasync(t1, "something else"); // count should 1 in t1, it's 2. assert.areequal(2 /* should 1*/, await queue.getcountasync(t1)); // broken! }
i need know whether design, , documentation incorrect, or whether bug. or if have misunderstood something.
any feedback appreciated.
thank reporting issue marten. bug in reliable queue. fix possible. apologize inconvenience.
i update on thread when issue fixed.
Comments
Post a Comment