On Apr 9, 2020, at 10:33 AM, Howard Chu hyc@symas.com wrote:
There is no point in nesting a read-only txn. Nesting is used to allow work to be subdivided so that one set of writes can be rolled back independently of the rest of the txn. In a readonly txn there is never anything to rollback.
This is what I figured, albeit from what I can glean, the system doesn’t complain if you do. But then my only experience with LMDB is this one Ruby binding I inherited, and I am trying to reconcile how the previous author designed the transaction code to work with the behaviour I observe.
- Must (read-only) transactions always be in a single hierarchy per thread or can there be many “roots” at once?
I don't understand the question. There must be no more than one read transaction per thread.
The transaction code in this binding module is organized in terms of a hash table keyed by thread ID, which doesn’t discriminate between read-only and read-write threads. When the Ruby code calls the C code, it replaces value in the hash for that thread with the new transaction (via a proxy struct) and then sets the ‘parent’ member to the outer transaction. This sounds like it is probably wrong for a number of reasons.
This is good information.
- Given that the relevant LMDB structs appear not to discriminate between transaction types, are there consequences for opening, e.g., a read-write transaction subordinate to a read-only one?
That will fail.
It reads then like there can only be one “root” transaction per thread, and if that transaction is read-write, then it is the only one for the environment. Conversely, if the transaction is read-only, it makes no sense to nest, so any nesting behaviour invoked from Ruby should be a no-op. I suppose it would further make no sense to nest a read-only transaction under a read-write, even though it appears that nothing prevents this.
Furthermore an attempt to open a read-write transaction under a read-only one should raise an exception in Ruby.
Tracking the existence of transactions in a language binding is almost certainly a wrong thing to do, completely unnecessary.
This is my feeling too.
This brings me to another issue: to behave properly, the binding will definitely need to know whether whatever comes out of mdb_active_txn() is read-only or not. Problem is, txn->mt_flags is not exposed. I filed a patch on March 20 for a function that returns them: https://bugs.openldap.org/show_bug.cgi?id=9188 .
Ironically it seems somebody else did the same in April 2019, but I didn’t catch it: https://bugs.openldap.org/show_bug.cgi?id=9011
Thanks for your response,
-- Dorian Taylor Make things. Make sense. https://doriantaylor.com tel:+1-604-723-5755 callto:doriantaylor