9

I use two different events for the callback to respond when the IndexedDB transaction finishes or is successful:

Let's say... db : IDBDatabase object, tr : IDBTransaction object, os : IDBObjectStore object

tr = db.transaction(os_name,'readwrite');
os = tr.objectStore();

case 1 :

r = os.openCursor();
r.onsuccess = function() {
    if(r.result){
        callback_for_result_fetched();
        r.result.continue;
    } else {
        callback_for_transaction_finish();
    }
}

case 2:

tr.oncomplete = callback_for_transaction_finish();

It is a waste if both of them work similarly. So can you tell me, is there any difference between them?

0

3 Answers 3

13

Sorry for raising up quite an old thread, but it's questioning is a good starting point...

I've looked for a similar question but in a bit different use case and actually found no good answers or even a misleading ones.

Think of a use case when you need to make several writes into the objectStore of even into several ones. You definitely don't want to manage each single write and it's own success and error events. That is the meaning of transaction and this is the (proper) implementation of it for indexedDB:

var trx = dbInstance.transaction([storeIdA, storeIdB], 'readwrite'),
    storeA = trx.objectStore(storeIdA),
    storeB = trx.objectStore(storeIdB);

    trx.oncomplete = function(event) {
        // this code will run only when ALL of the following requests are succeed
        // and only AFTER ALL of them were processed
    };
    trx.onerror = function(error) {
        // this code will run if ANY of the following requests will fail
        // and only AFTER ALL of them were processed
    };

    storeA.put({ key:keyA, value:valueA });
    storeA.put({ key:keyB, value:valueB });
    storeB.put({ key:keyA, value:valueA });
    storeB.put({ key:keyB, value:valueB });

Clue to this understanding is to be found in the following statement of W3C spec:

To determine if a transaction has completed successfully, listen to the transaction’s complete event rather than the success event of a particular request, because the transaction may still fail after the success event fires.

3
  • just what i was looking for. i assume objectStore.onsuccess, and objectStore.oncomplete can also be used for multi .add, . get, .put, etc... on given objectstore. Commented Oct 15, 2016 at 7:39
  • do you need trx.commit()? And for reading, if I want to do flatmap from multiple stores, should I do it with onSuccess instead? I have a wrapper function to make all of them async functions.
    – Pui Ho Lam
    Commented Aug 27, 2024 at 18:13
  • 1
    @PuiHoLam commit MAY be called but not MUST to (if called will commit the changes immediately, if not - I believe it'll happen at the end of the current microtask, but see more here. Regarding onSuccess vs onComplete - well, it's up to your requirement, either do it in any case or only in success case.
    – GullerYA
    Commented Aug 28, 2024 at 7:59
11

While it's true these callbacks function similarly they are not the same: the difference between onsuccess and oncomplete is that transactions complete but requests, which are made on those transactions, are successful.

oncomplete is only defined in the spec as related to a transaction. A transaction doesn't have an onsuccess callback.

2
  • did you mean that when a transaction is complete, that doesn't mean the the whole processing is successful, innit? Commented Jun 22, 2012 at 4:02
  • 2
    yes, it means the transaction has gone out of scope and was committed
    – buley
    Commented Jun 22, 2012 at 4:21
2

I would only caution that there is no garentee that getting a successful trx.oncomplete means the data was written to the disk/database:

We are seeing a problem with trx.oncomplete where the data is not being written to the db on disk. FireFox has an explanation of what they did that is causing this problem here: https://developer.mozilla.org/en-US/docs/Web/API/IDBTransaction/oncomplete

It seems that windows/edge is also having the same issue. Basically, there is no guarantee that your app will have data written to the database, if/when the user decides to kill or power down the device. We've even tried waiting up to 15 minutes before shutting down in some cases and haven't seen the data written. For me I'd always want to ensure that a data write completes and is committed.

Are there other solutions for a real persistent database, or enhancements to the IndexedDB beyond FF experimental add...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.