Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IndexedDB transaction.oncomplete with multiple actions

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?

like image 304
Semicolon Avatar asked Sep 26 '22 20:09

Semicolon


2 Answers

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.)

like image 139
Semicolon Avatar answered Sep 30 '22 13:09

Semicolon


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?

like image 37
Kristof Degrave Avatar answered Sep 30 '22 13:09

Kristof Degrave