9

I have the following array of objects which i want to add to and indexedDb:

const data = [
    { name: 'abc',
      color: 'blue'
    },
    { name: 'xyz',
      color: 'red'
    },
    { name: 'yui',
      color: 'black'
    }];

Now i create the database and insert this data into a store like this:

if (!db.objectStoreNames.contains("people")) {
        peopleStore = db.createObjectStore("people", { keyPath: "name" });
        peopleStore.createIndex("color", "color", { unique: false });

        peopleStore.transaction.oncomplete = function(event) {
            data.forEach(function(data) {
                operations.add(data);
            });
        };
    }

I have defined a function expression with an add() (inside a const operations) method like shown below:

add: function(data) {
            let request = db
                .transaction(["people"], "readwrite")
                .objectStore("people")
                .add(data);
        }

So here are my questions:

  1. Is this way creating a new transaction every time the add() method is being called or is it inserting all data in a single transaction?

  2. If it is creating a new transaction every time, how can i make only 1 transaction to improve performance and perform all operations in it only. I am guessing i have to create a global variable with the transaction and perform operations on it (there are other methods too, like edit(), delete(), etc., with each one of them having a "request" variable inside them defining a transaction, similar to what i have shown above). should i make a global variable something like this:

const globalTrans = db.transaction(["people"], "readwrite").objectStore("people");

  1. Is creating a new transaction a costly operation?

Thanks in advance to everyone who takes their time to reply! :)

Devashish
  • 1,260
  • 1
  • 10
  • 21

1 Answers1

8

Creating global variable will create issue. It might be that a transaction is runing and for another operation you might overwrite it.

e.g -

var globalTx;
// let's say you are selecting data from people
globalTx = db.transaction(["people"], "read")  // in read access
// and at same time you are inserting data from employee
globalTx = db.transaction(["employee"], "readwrite") // in read write

There are many ways to solve the issue -

  1. Create multiple methods based on scenario -
// for single value
function add(data) {
    let request = db.transaction(["people"], "readwrite").objectStore("people").add(data);
}

// for multiple value
function addMultiple(datas, callback) {
    const tx = db.transaction(["people"], "readwrite");

    datas.forEach(data => {
        let request = tx.objectStore("people").add(data);
    })

    tx.oncomplete = function(event) {
        callback();
    }
};
  1. Modify the function to only receive array values -
// so now data will be only array    
function add(datas, callback) {
    const tx = db.transaction(["people"], "readwrite");

    datas.forEach(data => {
        let request = tx.objectStore("people").add(data);
    })

    tx.oncomplete = function(event) {
        callback();
    }
};

// so when want to insert single value , we will call like this.

const value = {
    id: 1,
    name: 'ujjwal'
}
add([value], () => {

})

Hope this answers your question.

Ujjwal Kumar Gupta
  • 2,308
  • 1
  • 21
  • 32
  • Just a note... In your `function addMultiple(data, callback)` this line `let request = tx.objectStore("people").add(data);` should read `let request = tx.objectStore("people").add(value);`. NOTE the 'value' change – Gwasshoppa Oct 04 '20 at 23:32
  • aha right, thanks for pointing out. Have updated codes. – Ujjwal Kumar Gupta Oct 05 '20 at 09:41
  • How does indexedDB know when to commit the transaction? When is it going to call `tx.complete`? – d512 Jan 27 '22 at 19:30
  • So I don't have to check individual insert operations for errors and all I need is check it on the transaction level? And if one insert fails, will the whole transaction rollback? – icl7126 Mar 21 '22 at 12:40
  • when transaction created is inactive then it automatically commits – Ujjwal Kumar Gupta Mar 22 '22 at 05:03
  • 1
    you can also catch error on each insertion or you can watch on the whole transaction. Indexeddb is transactional database, so if one of tx fails then whole tx is aborted. – Ujjwal Kumar Gupta Mar 22 '22 at 05:04