IndexedDB
Use transactions and unblock upgrades
Group related writes atomically and close stale connections when another tab needs a newer database version.
8 minute lesson
IndexedDB writes already run in transactions. Use one explicit transaction when several records form one application operation.
Open a readwrite transaction, perform the related requests, then await tx.done. If one request aborts the transaction, none of its writes commit.
const tx = db.transaction(['notes', 'changes'], 'readwrite')
await tx.objectStore('notes').put(note)
await tx.objectStore('changes').add({ noteId: note.id, type: 'saved' })
await tx.done
Do not wait for unrelated network work in the middle of a transaction. IndexedDB transactions can become inactive when no database request remains pending.
Another open tab can block a version upgrade. Use the wrapper’s blocking() callback to close the old connection and tell the user to refresh rather than leaving the upgrade hanging.
Create a second changes store in version 3. Force its write to fail and prove the note does not commit. Open an older tab, trigger version 3 elsewhere, and handle the blocked upgrade clearly.
Lesson completed