On Apr 13, 2020, at 1:21 PM, Ulrich Windl Ulrich.Windl@rz.uni-regensburg.de wrote:
On 4/9/20 7:33 PM, Howard Chu wrote: [...]
Tracking the existence of transactions in a language binding is almost certainly a wrong thing to do, completely unnecessary.
MHO: Actually as you must either abort or commit any transaction, any long-running application would need to keep track of active transactions. Complex control flows may need such.
How does LMDB react if you try to abort a committed transaction, or trying to commit an aborted transaction (the other two cases should be idempontent, hopefully)? Such tings could happen easily if the application does not track the state of active transactions.
Indeed, there are a number of situations where the binding needs to know if there is a transaction open or not. There are for instance a number of quasi-atomic operations that are silently wrapped in a transaction for the convenience of the downstream programmer. Even when wrapped explicitly in a transaction, the binding will still need to resolve it somehow to know whether to do a no-op.
There is another scenario when a transaction is handed a block of code that explicitly starts another transaction. Again it will have to be able to tell whether to treat any attempt at nested transaction(s) as a no-op (or error). At the very least it will need access to the “parent” transaction.
So I agree that a modicum of bookkeeping is actually warranted, although I also agree with Howard that any existing bookkeeping within LMDB proper ought not to be duplicated. The main mistake of this implementation (located at https://github.com/doriantaylor/lmdb/blob/reconcile-2.7/ext/lmdb_ext/lmdb_ex...) I think is not distinguishing between read-only and read-write transactions, and further reduplicating the records in a way that one can easily lose track.
I am having trouble seeing how I can get rid of a lookup table (keyed by thread) for read-only transactions, and some mechanism for identifying any unitary read-write transaction. At this point however I am not aware of how to do this just using the LMDB API. `MDB_txn` is opaque and certain members can’t be accessed without specific concessions in the API.
Reading the LMDB source code (https://github.com/LMDB/lmdb/blob/mdb.master/libraries/liblmdb/mdb.c#L3144) it appears however that `mdb_txn_begin` will throw different error codes depending on the characteristics of the parent. This may be sufficient to route the appropriate behaviour, but one will still need to be able to retrieve a record of the parent in order to make that assessment.
-- Dorian Taylor Make things. Make sense. https://doriantaylor.com