Signatur
Beschreibung
Das abort-Ereignis zeigt an, dass eine IndexedDB-Transaktion nicht festgeschrieben wurde. Alle Änderungen, die innerhalb der Transaktion vorgenommen wurden, werden zurückgerollt; die Datenbank bleibt im Zustand vor Beginn der Transaktion. Sie registrieren den Handler entweder mit transaction.addEventListener("abort", handler) oder über die Eigenschaft transaction.onabort.
Ein Abbruch kann mehrere Ursachen haben:
- Expliziter Aufruf von
transaction.abort()im eigenen Code. - Eine Anfrage (
IDBRequest) schlägt fehl, z. B.ConstraintErrorbei doppeltem Schlüssel mitadd(), und der Fehler wird imerror-Handler nicht mitevent.preventDefault()abgefangen. - Der Speicherplatz reicht nicht aus (
QuotaExceededError) oder es tritt ein interner I/O-Fehler auf. - Die Datenbankverbindung wird geschlossen, während die Transaktion noch läuft (bei
versionchange-Transaktionen z. B. durchdb.close()).
Das Ereignis ist ein einfaches Event, bubbelt (von der Transaktion zur IDBDatabase) und ist nicht abbrechbar. Die Ursache ermitteln Sie über transaction.error: Bei einem manuellen abort() ist sie null, sonst ein DOMException-Objekt. Nach abort wird niemals complete ausgelöst – beide Ereignisse schließen sich gegenseitig aus.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "abort". |
|
| $handler Pflicht | (event: Event) => void | Callback, der beim Abbruch aufgerufen wird. event.target ist die abgebrochene IDBTransaction (bzw. beim Bubbling zur Datenbank ebenfalls die Transaktion). |
|
| $options | boolean | AddEventListenerOptions | false | Optionale Listener-Optionen wie once, capture oder signal. |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler erhält ein Event-Objekt vom Typ "abort".Beispiele
Abbruch per addEventListener erkennen und Ursache auswerten
const request = indexedDB.open('shop', 1);
request.onupgradeneeded = () => {
request.result.createObjectStore('produkte', { keyPath: 'id' });
};
request.onsuccess = () => {
const db = request.result;
const tx = db.transaction('produkte', 'readwrite');
tx.addEventListener('abort', () => {
// tx.error ist null bei manuellem abort(), sonst eine DOMException
console.log('Transaktion abgebrochen:', tx.error?.name ?? 'manuell');
});
tx.addEventListener('complete', () => console.log('Gespeichert'));
const store = tx.objectStore('produkte');
store.add({ id: 1, name: 'Tasse' });
store.add({ id: 1, name: 'Teller' }); // gleicher Schlüssel -> ConstraintError
};
Manueller Abbruch über onabort bei ungültigen Daten
const speichereBestellung = (db, bestellung) => new Promise((resolve, reject) => {
const tx = db.transaction('bestellungen', 'readwrite');
tx.oncomplete = () => resolve('ok');
tx.onabort = () => reject(tx.error ?? new Error('Vom Code abgebrochen'));
tx.objectStore('bestellungen').put(bestellung);
if (bestellung.menge <= 0) {
tx.abort(); // put() wird zurückgerollt
}
});
// Nutzung (db ist eine geöffnete IDBDatabase):
// try { await speichereBestellung(db, { id: 7, menge: 0 }); }
// catch (e) { console.log(e.message); }
Listener wieder entfernen
const onAbort = (event) => {
console.warn('Abbruch in Transaktion:', event.target.mode);
};
const tx = db.transaction('produkte', 'readonly');
tx.addEventListener('abort', onAbort);
// Später, z. B. beim Aufräumen einer Komponente:
tx.removeEventListener('abort', onAbort);
// Alternativ bei on-Property: tx.onabort = null;
Zentrale Überwachung über Bubbling an der Datenbank
const request = indexedDB.open('shop', 1);
request.onsuccess = () => {
const db = request.result;
// Fängt abort-Ereignisse ALLER Transaktionen dieser Verbindung
db.addEventListener('abort', (event) => {
const tx = event.target;
console.error(`Transaktion auf [${[...tx.objectStoreNames]}] abgebrochen`, tx.error);
});
};
// Wichtig · Fallstricke
- Unbehandelte Request-Fehler brechen die Transaktion ab: Schlägt eine einzelne Anfrage fehl, wird zuerst
erroram Request (bubbelnd zu Transaktion und Datenbank) ausgelöst. Rufen Sie dort nichtevent.preventDefault()auf, folgt automatischabort– alle bisherigen Änderungen gehen verloren. transaction.errorprüfen: Bei manuellemabort()ist der Wertnull. Code wietx.error.nameohne Optional Chaining wirft dann einenTypeError.- Bubbling beachten: Ein
abort-Listener an derIDBDatabaseempfängt die Ereignisse aller Transaktionen. Nicht zu verwechseln mit demabort-Ereignis vonAbortSignaloderXMLHttpRequest. - Kein
completenachabort: Behandeln Sie beide Ereignisse (sowie ggf.error), sonst bleibt z. B. ein Promise-Wrapper für immer offen. - Upgrade-Abbruch: Wird die
versionchange-Transaktion inonupgradeneededabgebrochen, schlägt auch deropen()-Request mitAbortErrorfehl, und die Versionsnummer bleibt unverändert. - Kompatibilität: In allen modernen Browsern und in Web Workern verfügbar. Im privaten Modus älterer Safari- bzw. Firefox-Versionen war IndexedDB teilweise eingeschränkt;
QuotaExceededError-Abbrüche treten dort früher auf.