9

My code is like the following:

...
var f1 = function(trans) {
  var store = trans.objectStore('ObjectStore');
  store.clear();
};
var f2 = function(trans) {
  var store = trans.objectStore('ObjectStore');
  store.add({id: 1, data: 'text'});
};
...
var trans = DB.connection.transaction(['ObjectStore'], IDBTransaction.READ_WRITE);
trans.onerror = function() { alert('ERROR'); };
trans.oncomplete = function() { alert('DONE'); };
...

The problem us that i get the DONE alert right after clear and on the second request exception appears.

Is it possible to "reuse" the transaction in IndexedDB?

UPD: I've found that the code above works as I expect in the latest Chromium nightly build.

Fedor
  • 1,392
  • 1
  • 17
  • 30

1 Answers1

5

According to Jonas Sicking, a Mozilla dev and co-spec writer for IndexedDB, a transaction is committed when the last callback fires. So to keep a transaction alive, you should be able to reuse it via successive callbacks.

You're using oncomplete above, but onsucess should work equally as well.

You can find the transaction object as an attribute of the request object that's returned on callback.

The following sentence isn't correct "Transactions today auto-commit when the transaction variable goes out of scope and no more requests can be placed against it".

Transaction never automatically commit when a variable goes out of scope. Generally they only commit when the last success/error callback fires and that callback schedules no more requests. So it's not related to the scope of any variables.

The only exception to this is if you create a transaction but place no requests against it. In that case the transaction is "committed" (whatever that means for a transaction which has no requests) as soon as you return to the event loop. In this scenario you could technically "commit" the transaction as soon as all references to it go out of scope, but it's not a particularly interesting use case to optimize.

Based on a spec example below, you should be able to find the transaction object at evt.transaction, and you can do a new transaction and add a new onsuccess event listener.

 var request = indexedDB.open('AddressBook', 'Address Book');
 request.onsuccess = function(evt) {...};
 request.onerror = function(evt) {...};
buley
  • 28,032
  • 17
  • 85
  • 106
  • Thank you for the answer. Could you please give an example? – Fedor May 08 '12 at 06:04
  • It's hard to post full example code for IDB (needs object store creation and data addition setup code before you can query) but I've added a bit about where you can find the transaction (it's an attribute of the object passed to `onsuccess`). Using that transaction object is like using any other transaction object so whatever code you have for that should work again there. – buley May 08 '12 at 20:18
  • For me the transaction is in `evt.target.transaction`. – Jon Dec 16 '20 at 14:03