jakearchibald / idb

IndexedDB, but with promises
https://www.npmjs.com/package/idb
ISC License
6.2k stars 348 forks source link

Tx does not rollback ? #269

Open enriquemolinari opened 2 years ago

enriquemolinari commented 2 years ago

Hi ! I pasted a pretty simple example using transactions with two object stores. After creating the stores on the openIndexedDb() function, the code opens a Tx and add an object to one store (STORE_DB) and then tries to add other object to the other store (STORE_QUEUE). That lines fails due to there is a typo in the name of the key (it is declared as queueTime and the object to add has a property called queuedTime). The thing is that even when these statements are in a Tx, the first line is commit into the object store (STORE_DB). Why? anything wrong am I doing?

const DB_NAME = "taskdb";
const STORE_DB = "db1";
const STORE_QUEUE = "queue";

async function openIndexedDb() {
    return await openDB(DB_NAME, 1, {
      upgrade(db) {
        initializeDatabase(db);
      },
    });
  }
  function initializeDatabase(db) {
    if (!db.objectStoreNames.contains(STORE_DB)) {
      let dbStore = db.createObjectStore(STORE_DB, {
        keyPath: "id",
      });
    }
    if (!db.objectStoreNames.contains(STORE_QUEUE)) {
      let queueStore = db.createObjectStore(STORE_QUEUE, {
        keyPath: "queueTime",
      });
    }
  }

  let db = await openIndexedDb();
  const tx = db.transaction([STORE_DB, STORE_QUEUE], "readwrite");
  await tx.objectStore(STORE_DB).add({ id: 1123, bla: 1 }); //this works
  await tx.objectStore(STORE_QUEUE).add({ queuedTime: Date.now(), id: 11 }); //this fails, but the previous line gets committed !
  await tx.done;
enriquemolinari commented 2 years ago

I had to do this to have the atomic behaviour:

let tx;
try {
   tx = db.transaction([STORE_DB, STORE_QUEUE], "readwrite");
   await tx.objectStore(STORE_DB).add({ id: 511, bla: 1 });
   await tx.objectStore(STORE_QUEUE).add({ queuedTime: Date.now(), id: 11 });
   await tx.done;
} catch (e) {
   tx.abort();
}