问题
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.
回答1:
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) {...};
来源:https://stackoverflow.com/questions/10484965/how-can-i-put-several-requests-in-one-transaction-in-indexeddb