0

I have some js that does a put to IndexedDB (in Chrome) using a readwrite transaction, then immediately queries from the same indexedDB objectstore using an index and a readonly transaction. Sometimes, the results I get back do not include the changes from my put and other times they. Is this sort of dirty ready to be expected in IndexedDB? Is there a way to avoid it?

Perhaps it's because I'm using 2 different txns and should be using just one (the reason for that is these calls are actually part of an api that separates puts and queries into different api calls that each have their own txns)? Still, seems like the first txn should be done and committed before my second one starts.

My pseudocode looks like this:

var txn = idb.transaction([DOC_STORE], "readwrite");
var putRequest = txn.objectStore(DOC_STORE).put(myDoc);
putRequest.onsuccess = function (e) {
    var txn2 = idb.transaction([DOC_STORE], "readonly");
    var store = txn2.objectStore(DOC_STORE);
    var anotherRequest=store.index.openCursor();
    .... walk the cursor here. Sometimes I don't see my changes from my put
};
Category6
  • 516
  • 5
  • 19
  • The assumption that the first transaction should commit before the second one starts seems correct to me. The OPs problem may have been dune to an IndexedDB implementation bug. Does this still occur for anyone, in current browsers? – Doin Mar 22 '21 at 14:31

1 Answers1

2

You have to wait for the write transaction to complete. It comes later than request success event.

var txn = idb.transaction([DOC_STORE], "readwrite");
var putRequest = txn.objectStore(DOC_STORE).put(myDoc);
txn.oncomplete = function (e) {
    var txn2 = idb.transaction([DOC_STORE], "readonly");
    var store = txn2.objectStore(DOC_STORE);
    var anotherRequest=store.index.openCursor();
    .... walk the cursor here. You will see see your all changes from your put
};

Alternatively, you can use request success in same transaction.

var txn = idb.transaction([DOC_STORE], "readwrite");
var putRequest = txn.objectStore(DOC_STORE).put(myDoc);
putRequest.onsuccess = function (e) {
    var store = txn.objectStore(DOC_STORE);
    var anotherRequest=store.index.openCursor();
    .... walk the cursor here. You will see see your all changes from your put
};
Kyaw Tun
  • 12,447
  • 10
  • 56
  • 83
  • I realize I'm 8 years late here, but I don't think this answers the fundamental problem of why the OP's 2nd transaction sees data from _before_ the first transaction. Transactions lock the tables they apply to, so it should ***not*** be possible for the 2nd transaction to begin until the readwrite lock held by the 1st one is released, at which point the data should have been written already. In fact the reported behavior violates section 2.7.2 of the spec - see the last bullet point here: https://www.w3.org/TR/IndexedDB/#transaction-scheduling – Doin Mar 22 '21 at 14:25
  • The OPs problem thus stems from a bug in his browser's IndexedDB implementation. I suspect it would no longer occur in a current browser. The answer here should thus be taken as a workaround for dealing with very old, buggy IndexedDB implementations, and definitely not as "correct practice". – Doin Mar 22 '21 at 14:26