Signatur
Beschreibung
Die Eigenschaft transaction eines IDBObjectStore verweist auf die IDBTransaction, über die der Objektspeicher geöffnet wurde. In IndexedDB ist jeder Zugriff auf einen Objektspeicher an genau eine Transaktion gebunden. Über diese Eigenschaft gelangt man vom Speicher zurück zu seiner Transaktion.
Nützlich ist das vor allem, wenn eine Hilfsfunktion nur den Objektspeicher als Argument bekommt, aber trotzdem auf Ereignisse der Transaktion (complete, error, abort) reagieren, den Modus (mode) prüfen oder die Transaktion mit abort() abbrechen soll. Auch die übrigen Speicher derselben Transaktion erreicht man so über store.transaction.objectStore(name).
Im upgradeneeded-Handler gibt db.createObjectStore() einen Speicher zurück, dessen transaction die laufende versionchange-Transaktion ist. Darüber lässt sich erkennen, wann das Schema-Upgrade abgeschlossen ist, etwa um danach Startdaten einzufügen.
Rückgabewert
"readonly", "readwrite" oder "versionchange".Beispiele
Vom Objektspeicher zur Transaktion zurückgehen
const request = indexedDB.open('shop', 1);
request.onupgradeneeded = () => {
request.result.createObjectStore('produkte', { keyPath: 'id' });
};
request.onsuccess = () => {
const db = request.result;
const store = db.transaction('produkte', 'readwrite').objectStore('produkte');
console.log(store.transaction.mode);
console.log([...store.transaction.objectStoreNames]);
store.put({ id: 1, name: 'Tastatur', preis: 49 });
store.transaction.oncomplete = () => console.log('Gespeichert');
};
Hilfsfunktion, die nur den Speicher erhält, als Promise
// Schreibt mehrere Datensätze und wartet auf das Ende der Transaktion
const putAll = (store, items) => new Promise((resolve, reject) => {
const tx = store.transaction;
if (tx.mode === 'readonly') {
reject(new Error('Schreibtransaktion erforderlich'));
return;
}
items.forEach((item) => store.put(item));
tx.oncomplete = () => resolve(items.length);
tx.onerror = () => reject(tx.error);
tx.onabort = () => reject(tx.error ?? new Error('Abgebrochen'));
});
// Nutzung (db ist eine geöffnete IDBDatabase):
// const store = db.transaction('produkte', 'readwrite').objectStore('produkte');
// const anzahl = await putAll(store, [{ id: 2, name: 'Maus' }, { id: 3, name: 'Monitor' }]);
// console.log(`${anzahl} Datensätze gespeichert`);
Startdaten nach dem Schema-Upgrade einfügen
const request = indexedDB.open('app', 1);
request.onupgradeneeded = () => {
const db = request.result;
const store = db.createObjectStore('einstellungen', { keyPath: 'schluessel' });
// store.transaction ist die versionchange-Transaktion
console.log(store.transaction.mode);
store.transaction.oncomplete = () => {
const tx = db.transaction('einstellungen', 'readwrite');
tx.objectStore('einstellungen').put({ schluessel: 'theme', wert: 'dunkel' });
tx.oncomplete = () => console.log('Startdaten angelegt');
};
};
// Wichtig · Fallstricke
- Die Eigenschaft ist schreibgeschützt. Eine Zuweisung wird ignoriert bzw. wirft im Strict Mode einen
TypeError. - Die Transaktion bleibt über den Speicher auch dann erreichbar, wenn sie schon beendet ist. Neue Anfragen wie
store.put()werfen dann aber eineTransactionInactiveError-DOMException. IndexedDB-Transaktionen schließen sich automatisch, sobald keine Anfragen mehr offen sind. Deshalb dürfen zwischen den Anfragen keineawait-Aufrufe auf fremde Promises (z. B.fetch) stehen. - Jeder Aufruf von
db.transaction()erzeugt eine neue Transaktion. Ein Speicher, den man über eine andere Transaktion holt, ist ein anderesIDBObjectStore-Objekt mit einer anderentransaction. - Die Eigenschaft wird von allen modernen Browsern unterstützt, auch in Web Workern. In privaten Fenstern einiger Browser kann IndexedDB eingeschränkt sein.