Signatur
Beschreibung
objectStore() ist in IndexedDB der übliche Weg, um innerhalb einer Transaktion an einen konkreten Object Store zu kommen. Eine Transaktion legt man mit IDBDatabase.transaction(storeNames, mode) an. Dabei bestimmt man den Scope, also die Liste der Stores, auf die die Transaktion zugreifen darf. objectStore(name) liefert dann das IDBObjectStore-Objekt für einen dieser Stores. Über dieses Objekt ruft man Methoden wie get(), put(), add(), delete(), openCursor() oder index() auf.
Der zurückgegebene Store ist fest an die Transaktion gebunden, aus der er stammt. Alle Anfragen über dieses Objekt laufen innerhalb dieser Transaktion und gelten mit dem Zugriffsmodus, der dort festgelegt wurde ("readonly", "readwrite" oder "versionchange"). Ruft man die Methode in derselben Transaktion mehrmals mit demselben Namen auf, bekommt man laut Spezifikation jedes Mal dieselbe IDBObjectStore-Instanz zurück.
Sonderfall upgradeneeded: Während einer versionchange-Transaktion gehören alle Stores der Datenbank zum Scope. Über event.target.transaction.objectStore(name) kommt man dort an bestehende Stores, um zum Beispiel neue Indizes anzulegen oder Daten umzuziehen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $name Pflicht | string | Name des Object Stores, den man haben möchte. Der Store muss zum Scope der Transaktion gehören, also beim Aufruf von IDBDatabase.transaction() angegeben worden sein. |
Rückgabewert
IDBObjectStore-Objekt, über das man im Kontext dieser Transaktion auf den Store zugreift.Beispiele
Datensatz in einer readwrite-Transaktion speichern
const openDb = () => new Promise((resolve, reject) => {
const req = indexedDB.open('shop', 1);
req.onupgradeneeded = () => {
req.result.createObjectStore('produkte', { keyPath: 'id' });
};
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
});
const db = await openDb();
const tx = db.transaction('produkte', 'readwrite');
const store = tx.objectStore('produkte');
store.put({ id: 1, name: 'Tastatur', preis: 49.9 });
tx.oncomplete = () => console.log('Gespeichert');
tx.onerror = () => console.error(tx.error);
Mehrere Stores in einer Transaktion (atomar)
// Bestellung anlegen und Lagerbestand senken – entweder beides oder nichts
const tx = db.transaction(['bestellungen', 'lager'], 'readwrite');
const bestellungen = tx.objectStore('bestellungen');
const lager = tx.objectStore('lager');
const req = lager.get('artikel-42');
req.onsuccess = () => {
const eintrag = req.result;
if (!eintrag || eintrag.menge < 1) {
tx.abort(); // nichts wird geschrieben
return;
}
eintrag.menge -= 1;
lager.put(eintrag);
bestellungen.add({ artikel: 'artikel-42', datum: Date.now() });
};
tx.oncomplete = () => console.log('Bestellung abgeschlossen');
tx.onabort = () => console.warn('Bestellung abgebrochen');
Index in upgradeneeded auf bestehendem Store anlegen
const req = indexedDB.open('shop', 2);
req.onupgradeneeded = (event) => {
// Die versionchange-Transaktion umfasst alle Stores
const tx = event.target.transaction;
const store = tx.objectStore('produkte');
if (!store.indexNames.contains('nachName')) {
store.createIndex('nachName', 'name', { unique: false });
}
};
req.onsuccess = () => console.log('Upgrade fertig, Version', req.result.version);
Fehler bei einem Store außerhalb des Scopes abfangen
const tx = db.transaction('produkte', 'readonly');
try {
tx.objectStore('kunden'); // nicht im Scope
} catch (err) {
console.log(err.name);
}
// Wichtig · Fallstricke
NotFoundError(DOMException): Der angeforderte Store gehört nicht zum Scope der Transaktion. Das passiert auch dann, wenn der Store in der Datenbank existiert, beidb.transaction()aber nicht mit angegeben wurde.InvalidStateError: Die Transaktion ist schon abgeschlossen (complete) oder abgebrochen (abort).- Automatisches Commit: Eine Transaktion wird automatisch abgeschlossen, sobald keine Anfragen mehr offen sind und die Kontrolle an die Event-Loop zurückgeht. Wer zwischen
objectStore()und dem nächsten Request auf etwas anderes wartet (etwa mitawait fetch()odersetTimeout), bekommt beim nächsten Zugriff einenTransactionInactiveError. Asynchrone Arbeit deshalb vor oder nach der Transaktion erledigen. - Schreibende Methoden wie
put(),add()oderdelete()werfen in einer"readonly"-Transaktion einenReadOnlyError. - Den Store-Objekten nicht über das Ende der Transaktion hinaus vertrauen: Für jede neue Transaktion muss man
objectStore()neu aufrufen. - Kompatibilität: Die Methode wird in allen modernen Browsern und in Web Workern unterstützt. In privaten Fenstern mancher Browser ist IndexedDB eingeschränkt oder nur flüchtig verfügbar.