kriszyp / lmdb-js

Simple, efficient, ultra-fast, scalable data store wrapper for LMDB
Other
505 stars 41 forks source link

Question: what's the point of versioning if transactions achieve the same result? #221

Closed alexgleason closed 1 year ago

alexgleason commented 1 year ago

I want to store a JSON object as a value in LMDB. Later I want to update values inside it, while there are multiple processes potentially trying to do the same thing, without race conditions.

After reading through the README, the explanation on Concurrency and Versioning made sense as a solution (although I still don't know what happens when you db.put the wrong version - the function throws?)

But according to the README, db.transaction can achieve same benefits and guarantees without all the hassle of versioning. Is that really true?

return products.transaction(() => {
    let shoe = products.get('shoe')
    // this is performed atomically, so we can guarantee no other processes
    // modify this entry before we write the new value
    if (shoe.count > 0) {
        shoe.count--
        products.put('shoe', shoe)
        return true // succeeded
    }
    return false // count is zero, no shoes to buy
})
kriszyp commented 1 year ago

Yes, you are correct that db.transaction can achieve the same benefits and guarantees. However, with versioning, the version checks and conditional writes can be performed entirely in a separate worker writer thread, whereas db.transaction requires that the writer thread enqueue an event on the main JS thread and execute the transaction on the main JS thread. Therefore, using versioning has better performance and concurrency than using db.transaction.

db.put the wrong version

This (the returned promise) will resolve to false.

alexgleason commented 1 year ago

Thank you. That is extremely helpful!