treojs / treo

Consistent API to IndexedDB
http://treojs.com
MIT License
257 stars 18 forks source link

[0.6] Transaction becomes inactive too quickly #34

Open glsignal opened 9 years ago

glsignal commented 9 years ago

I've run into an odd issue using 0.6.0-rc2 where the transaction becomes inactive before nodeStore.add, do you have any ideas on why this might happen or how to avoid it? This implementation seems like a valid approach, but I might be missing something fundamental here.

    let tx = this.db.transaction(['nodes', 'assignments'], 'write');
    let assignmentStore = tx.store('assignments');
    let nodeStore = tx.store('nodes');

    let assignment = {
      title:        "Untitled (" + RandomName.get() + ")",
      description:  "Created " + new Date().toDateString()
    };

    // Populate the localId while we're here
    assignment.localId = await assignmentStore.add(assignment);

    let node = {
      localAssignmentId: assignment.localId,
      tabId:             payload.tabId,
      title:             payload.tabObj.title,
      url:               payload.tabObj.url
    };

    node.localId = await nodeStore.add(node);

    tx.then(() => { ...
alekseykulikov commented 9 years ago

Yes, it's a well known issue. And one of the reasons, why default treo API uses one transaction per operation.

From my experience it should work only in Chrome. Because it handles Promises and IDB transactions right. But in all other browsers you have to rely on onsuccess callback and schedule next operation synchronously.

Jake Archibald recently wrote great post explaining microtasks and how much there're inconsistency between browser implementations.

Try to use es6-promise, because it forces some browsers to use MutationObserver and it might help, but it most likely won't work with IndexedDBShim. Another idea is to generate localId manually and use Promise.all.

glsignal commented 9 years ago

Ah this old chestnut. I'd come across the microtask issue a while back (though not Jake's extremely well explained post), but had dismissed it as I'm working on Chrome exclusively.

I'll try out the polyfill and see how it goes, thanks for your comment :)