Start · Sprachen · JavaScript · Referenz · IDBTransaction.abort()

IDBTransaction.abort()

Methode

Bricht eine IndexedDB-Transaktion ab und macht alle Änderungen rückgängig, die innerhalb dieser Transaktion an der Datenbank vorgenommen wurden.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

IDBTransaction.prototype.abort()

Beschreibung

Mit abort() brechen Sie eine laufende IDBTransaction ab. Alle Schreibvorgänge der Transaktion, also add(), put(), delete() und clear(), werden verworfen. Die Datenbank bleibt so, wie sie vor Beginn der Transaktion war. IndexedDB-Transaktionen sind atomar: Entweder gelingen alle Operationen oder keine.

Nach dem Aufruf erhalten alle noch ausstehenden Anfragen (IDBRequest) der Transaktion ein error-Ereignis. Ihre error-Eigenschaft ist dann eine DOMException mit dem Namen AbortError. Danach wird auf der Transaktion das Ereignis abort ausgelöst. Das Ereignis complete tritt nicht ein.

Typische Anwendungsfälle:

  • Prüfung schlägt fehl: Mitten in einer mehrstufigen Operation stellt sich heraus, dass die Daten ungültig sind. Ein Beispiel ist eine Überweisung zwischen zwei Konten, bei der das Guthaben nicht reicht.
  • Abbruch durch den Nutzer: Ein längerer Import wird abgebrochen und soll keine halb geschriebenen Daten hinterlassen.
  • Schema-Migration verwerfen: In einer versionchange-Transaktion innerhalb von onupgradeneeded wird der Versionswechsel abgebrochen. Dann schlägt auch der Aufruf open() fehl.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined). Den Abbruch erkennen Sie am Ereignis abort der Transaktion.

Beispiele

Überweisung abbrechen, wenn das Guthaben nicht reicht

const transfer = (db, fromId, toId, amount) => new Promise((resolve, reject) => {
  const tx = db.transaction('accounts', 'readwrite');
  const store = tx.objectStore('accounts');

  tx.oncomplete = () => resolve('Überweisung ausgeführt');
  tx.onabort = () => reject(tx.error ?? new Error('Überweisung abgebrochen'));

  const req = store.get(fromId);
  req.onsuccess = () => {
    const from = req.result;
    if (!from || from.balance < amount) {
      // Nichts wird geschrieben, alle Änderungen werden verworfen
      tx.abort();
      return;
    }
    from.balance -= amount;
    store.put(from);

    const toReq = store.get(toId);
    toReq.onsuccess = () => {
      const to = toReq.result;
      to.balance += amount;
      store.put(to);
    };
  };
});

// Nutzung
transfer(db, 1, 2, 500)
  .then(console.log)
  .catch(err => console.warn('Fehlgeschlagen:', err.message));
Fehlgeschlagen: Überweisung abgebrochen

Import per Schaltfläche abbrechen

let currentTx = null;

const importItems = (db, items) => {
  currentTx = db.transaction('items', 'readwrite');
  const store = currentTx.objectStore('items');
  items.forEach(item => store.put(item));

  currentTx.oncomplete = () => console.log(`${items.length} Einträge importiert`);
  currentTx.onabort = () => console.log('Import abgebrochen, Datenbank unverändert');
};

document.querySelector('#cancel').addEventListener('click', () => {
  try {
    currentTx?.abort();
  } catch (err) {
    // InvalidStateError: Transaktion war bereits beendet
    console.log('Zu spät, der Import ist bereits abgeschlossen.');
  }
});
Import abgebrochen, Datenbank unverändert

Ausstehende Anfragen erhalten einen AbortError

const tx = db.transaction('notes', 'readwrite');
const req = tx.objectStore('notes').add({ id: 42, text: 'Entwurf' });

req.onerror = (event) => {
  console.log('Anfrage-Fehler:', req.error.name);
  event.preventDefault(); // verhindert, dass der Fehler weitergereicht wird
};
tx.onabort = () => console.log('Transaktion abgebrochen:', tx.error);

tx.abort();
Anfrage-Fehler: AbortError Transaktion abgebrochen: null

Schema-Upgrade in onupgradeneeded verwerfen

const request = indexedDB.open('shop', 3);

request.onupgradeneeded = (event) => {
  const db = request.result;
  const tx = request.transaction; // versionchange-Transaktion
  if (event.oldVersion > 0 && !db.objectStoreNames.contains('products')) {
    console.log('Unerwarteter Zustand, Upgrade wird abgebrochen');
    tx.abort();
    return;
  }
  if (!db.objectStoreNames.contains('orders')) {
    db.createObjectStore('orders', { keyPath: 'id' });
  }
};

request.onerror = () => console.log('open() fehlgeschlagen:', request.error.name);
Unerwarteter Zustand, Upgrade wird abgebrochen open() fehlgeschlagen: AbortError

// Wichtig · Fallstricke

  • InvalidStateError: abort() wirft eine DOMException vom Typ InvalidStateError, wenn die Transaktion bereits abgeschlossen oder abgebrochen ist. Das ist der Fall, nachdem complete oder abort ausgelöst wurde. Umschließen Sie späte Aufrufe deshalb mit try/catch.
  • Auto-Commit: Eine Transaktion wird automatisch abgeschlossen, sobald keine Anfragen mehr ausstehen und die Kontrolle an die Ereignisschleife zurückgeht. Nach einem await auf ein Promise, das nichts mit IndexedDB zu tun hat, etwa fetch(), ist die Transaktion oft schon beendet. Ein abort() kommt dann zu spät.
  • tx.error ist null, wenn Sie selbst abbrechen. Wurde die Transaktion durch einen Fehler abgebrochen, etwa einen ConstraintError oder QuotaExceededError, steht dort die auslösende Ausnahme.
  • Automatischer Abbruch: Ein nicht behandelter Fehler einer Anfrage bricht die gesamte Transaktion ab. Das passiert, wenn im error-Handler kein event.preventDefault() aufgerufen wird.
  • Bei readonly-Transaktionen gibt es nichts zurückzunehmen. Dort beendet abort() nur die ausstehenden Leseanfragen.
  • Kompatibilität: Wird von allen modernen Browsern und in Web Workern unterstützt. Das zugehörige tx.commit() für einen vorzeitigen Abschluss ist neuer (ab Chrome 76, Firefox 74, Safari 15).