Start · Sprachen · JavaScript · Referenz · IDBOpenDBRequest: blocked

IDBOpenDBRequest: blocked

Ereignis

Wird an einem <code>IDBOpenDBRequest</code> ausgelöst, wenn noch offene Verbindungen ein Versions-Upgrade oder das Löschen der Datenbank blockieren.

seit JavaScript Baseline: alle modernen Browser Kategorie: webapi

Signatur

request.addEventListener("blocked", handler)

Beschreibung

Das Ereignis blocked wird an einem IDBOpenDBRequest ausgelöst, wenn indexedDB.open() mit einer höheren Versionsnummer oder indexedDB.deleteDatabase() aufgerufen wird, während noch andere Verbindungen zur selben Datenbank offen sind, zum Beispiel in einem anderen Tab, einem Worker oder im eigenen Code. Vorher schickt der Browser jeder dieser Verbindungen ein versionchange-Ereignis. Schließt danach nicht jede Verbindung mit db.close(), wird blocked ausgelöst.

Der Handler lässt sich mit request.addEventListener("blocked", handler) oder über die Eigenschaft request.onblocked = handler registrieren. Das Ereignisobjekt ist ein IDBVersionChangeEvent mit oldVersion (aktuelle Version) und newVersion (gewünschte Version, bei deleteDatabase() ist sie null).

Wichtig: blocked ist kein Fehler, und die Anfrage wird nicht abgebrochen. Sie wartet weiter. Sobald alle anderen Verbindungen geschlossen sind, geht es mit upgradeneeded und success weiter (bzw. mit success beim Löschen). Typischerweise zeigt man im Handler einen Hinweis an, etwa „Bitte schließen Sie andere Tabs dieser Anwendung“.

Das Ereignis wird nicht weitergereicht (bubbling) und lässt sich nicht abbrechen. Am zuverlässigsten vermeidet man es, indem jede Verbindung auf versionchange mit db.close() reagiert.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Name des Ereignisses: "blocked".
$handler Pflicht (event: IDBVersionChangeEvent) => void Callback, der ein IDBVersionChangeEvent mit oldVersion und newVersion bekommt.
$options boolean | AddEventListenerOptions false Optionale Einstellungen für addEventListener, z. B. { once: true }.

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Der Handler bekommt ein IDBVersionChangeEvent.

Beispiele

Upgrade blockiert – Hinweis anzeigen (addEventListener)

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

request.addEventListener('blocked', (event) => {
  console.warn(`Upgrade von v${event.oldVersion} auf v${event.newVersion} blockiert.`);
  alert('Bitte schließen Sie andere Tabs dieser Anwendung, um fortzufahren.');
});

request.addEventListener('upgradeneeded', (event) => {
  const db = request.result;
  if (!db.objectStoreNames.contains('eintraege')) {
    db.createObjectStore('eintraege', { keyPath: 'id', autoIncrement: true });
  }
});

request.addEventListener('success', () => {
  console.log('Datenbank bereit, Version', request.result.version);
});
Upgrade von v2 auf v3 blockiert. Datenbank bereit, Version 3

Blockieren vermeiden: auf versionchange reagieren

const openDb = (name, version) => new Promise((resolve, reject) => {
  const req = indexedDB.open(name, version);
  req.onsuccess = () => {
    const db = req.result;
    // Andere Tabs wollen upgraden: eigene Verbindung freigeben
    db.onversionchange = () => {
      db.close();
      console.log('Verbindung geschlossen – neue Version verfügbar, bitte neu laden.');
    };
    resolve(db);
  };
  req.onerror = () => reject(req.error);
  req.onblocked = () => console.warn('Warte auf das Schließen anderer Verbindungen …');
});

const db = await openDb('notizen', 3);
console.log(db.name, db.version);
notizen 3

Datenbank löschen mit onblocked-Property

const deleteDb = (name) => new Promise((resolve, reject) => {
  const req = indexedDB.deleteDatabase(name);
  req.onblocked = (event) => {
    // Bei deleteDatabase ist newVersion null
    console.warn('Löschen blockiert, newVersion =', event.newVersion);
  };
  req.onsuccess = () => resolve('gelöscht');
  req.onerror = () => reject(req.error);
});

console.log(await deleteDb('notizen'));
Löschen blockiert, newVersion = null gelöscht

Eigene Verbindung als Ursache

const first = await new Promise((res) => {
  const r = indexedDB.open('demo', 1);
  r.onsuccess = () => res(r.result);
});

const upgrade = indexedDB.open('demo', 2);
upgrade.onblocked = () => {
  console.log('Blockiert durch eigene Verbindung – schließe sie.');
  first.close(); // danach läuft das Upgrade weiter
};
upgrade.onsuccess = () => console.log('Version jetzt', upgrade.result.version);
Blockiert durch eigene Verbindung – schließe sie. Version jetzt 2

// Wichtig · Fallstricke

  • Kein Abbruch: Nach blocked bleibt die Anfrage offen. Kommt kein db.close(), bleibt sie ohne Zeitlimit hängen. Bei Bedarf eine eigene Zeitüberwachung einbauen und den Nutzer informieren.
  • Reihenfolge: Zuerst bekommen die offenen Verbindungen versionchange. Schließen alle sofort, wird blocked gar nicht ausgelöst.
  • Häufige Ursache: Die eigene Anwendung hält eine alte Verbindung (Singleton, Service Worker, zweiter Tab). Jede Verbindung sollte einen onversionchange-Handler mit db.close() haben.
  • Bei deleteDatabase() ist event.newVersion gleich null.
  • Ältere Safari-Versionen hatten Fehler beim Auslösen von blocked. Ansonsten ist das Ereignis in allen modernen Browsern und in Workern verfügbar.
  • Im privaten Modus mancher Browser ist IndexedDB eingeschränkt oder flüchtig.