The question is: how does an IDBTransaction -- the kind you get from IDBDatabase, we'll call it type A -- know when to call oncomplete
if it can be include an arbitrary number of IDBTransaction (type B) children?
First, you get your 'type A' IDBTransaction from the database connection:
const transA = IDBDatabase.transaction(storeName, mode);
This IDBT may carry the oncomplete
event, and supposedly it will fire when the total transaction is complete. But you use this IDBT to 'launch' the real transactions via one or more retrieved IDBObjectStores:
const store = transA.objectStore(storeName);
const transB1 = store.delete(key);
const transB2 = store.add(item);
Now, transB1
and transB2
are also instances of IDBTransaction, which may have their own oncomplete
handlers. The idea of the parent transaction here, as I understand it, is that it permits the aggregate transaction to be atomic; if transB1 succeeds but transB2 fails, transB1 is rolled back. Good. So we'll generally be more interested in listening to the parent, not the children, since this is what tells us if it really succeeded.
The catch I don't get: there's no close
or done
or finish
method or whatever. So how does transA
actually know when to trigger oncomplete
?
All I can think of at the moment is that it expects all child transactions to be created during a single tick. Is that what's going on? (It's already pretty apparent that IndexedDB is painfully un-JS, but quietly relying on synchrony to imply behavior like that seems like a boundary even the DOM overlords would not cross.) What's really going on?
Answering my own after some experimentation.
The answer, it turns out, seems to be yes, that's really just how it works. Reliance on synchrony is true across the board -- not as surprising once it clicks that these aren't "real" event handlers in the first place (e.g. transaction.on('complete', ...)
) -- which means there's maybe no way at all to wrap indexedDB in an API that doesn't, to some extent, mirror its own horrific form. :(
(Not marking as accepted; maybe someone has more insight yet.)
The indexedDB API is designed to be autocommited. So when ever a transaction is getting idle it will be commited by default, so you don't need to do it manually like most SQL databases. This means the oncomplete callback will be called automatically when the transaction completes/ The only thing you can do manually is aborting the transaction.
Nested transaction like you want to have aren't possible in this API. Transactions are expected to be short-lived, so the browser can terminate a transaction that takes too long, in order to free up storage resources that the long-running transaction has locked.
Btw why should you need multiple transactions? You can do all the actions in a single transaction?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With