kriszyp / lmdb-js

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

Block a transaction commit? #115

Closed Llorx closed 2 years ago

Llorx commented 2 years ago

Hi,

I've been working with transactions. In other databases (MongoDB for example), if you throw an error inside a transaction, the transaction is not commited, so doing some puts and gets will not update the database if you later notice a problem in the values.

Here, if I throw an error, the transaction captures the error and rejects its own promise, but further readings to the database includes the put data, like so:

try {
    await db.transaction(() => {
        for (let i = 0; i < 10000; i++) {
            db.put("test" + i, "test");
        }
        throw new Error("test error");
    });
} catch (e) {
    console.log(e);
}
await db.transaction(() => {
    console.log(db.get("test5000"));
});

Here, I expected the second transaction not reading the "test5000" value, as the transaction before was "errored", but it actually reads it. Is that what I should expect or is a bug?

If that's correct, how can I actually block the transaction from commiting?

kriszyp commented 2 years ago

That's the way transaction works since operating without rollbacks is a little faster default, but if you want (asynchronous) transactions to be abortable, just explicitly use childTransaction instead of a transaction. I tried with your code, and it works as you expect, rolling back the puts, so the subsequent get returns undefined: https://github.com/DoctorEvidence/lmdb-js#dbchildtransactioncallback-function-promise

Llorx commented 2 years ago

Ohh I see. Thank you. The worse part is I've read about them, but my brain didn't click...