Закрытие и удаление базы данных

В Dexie.js каждое соединение с базой данных представляет собой активный экземпляр обёртки над IndexedDB. Пока экземпляр открыт, браузер удерживает внутренние ресурсы: соединения, курсоры, кэш схемы и обработчики транзакций. Корректное закрытие становится критически важным в сценариях переключения контекста приложения, уничтожения модулей или перед удалением базы.

Метод закрытия экземпляра

Закрытие выполняется через метод экземпляра:

db.close();

После вызова соединение переводится в неактивное состояние:

  • все текущие транзакции завершаются или прерываются в зависимости от стадии выполнения;
  • новые запросы не инициируются;
  • внутренний пул соединений IndexedDB освобождается.

Особенность поведения заключается в том, что close() не является асинхронным методом. Он не возвращает Promise и выполняется синхронно с точки зрения API Dexie, хотя фактическое завершение операций происходит на уровне браузера.

Состояние после закрытия

После закрытия экземпляр можно считать «пассивным». При этом:

  • вызовы методов таблиц не выполняются корректно;
  • транзакции не создаются;
  • повторное использование возможно только после повторного open().
db.close();
await db.open();

Повторное открытие приводит к повторной инициализации схемы, если это требуется, но без изменения версии базы.

Поведение активных транзакций

Если во время вызова db.close() существуют активные транзакции:

  • они доводятся до завершения, если находятся в стадии чтения;
  • операции записи могут быть прерваны браузером;
  • возможны ошибки InvalidStateError при попытке продолжить выполнение.

Поэтому закрытие соединения логически корректно выполнять вне активных операций записи.


Удаление базы данных

Удаление базы данных в Dexie.js выполняется на уровне всей IndexedDB-базы, а не отдельных таблиц. Это операция уничтожает:

  • все таблицы;
  • все индексы;
  • все данные;
  • метаданные схемы.

Требование закрытого соединения

Перед удалением необходимо гарантировать отсутствие активных подключений. IndexedDB блокирует удаление базы, если существуют открытые соединения.

Стандартный порядок:

db.close();
await Dexie.delete('myDatabase');

При несоблюдении этого порядка операция удаления может быть отклонена браузером или поставлена в очередь до освобождения блокировки.

Метод удаления Dexie

Удаление выполняется через статический метод:

await Dexie.delete('myDatabase');

Метод возвращает Promise, который:

  • выполняется при успешном удалении;
  • отклоняется при ошибке доступа или активных соединениях.

Проверка существования базы

Перед удалением часто используется проверка:

const exists = await Dexie.exists('myDatabase');

Это позволяет избежать лишних операций, особенно в сценариях инициализации или сброса состояния приложения.


Блокировки и поведение в нескольких вкладках

IndexedDB работает с моделью блокировок, где одновременно может существовать несколько соединений из разных вкладок браузера.

Событие блокировки

Dexie предоставляет механизм обработки ситуации, когда удаление или обновление базы невозможно из-за открытых соединений:

db.on('blocked', () => {
    // обработка ситуации блокировки
});

Это событие возникает в случаях:

  • попытка удалить базу при открытой другой вкладке;
  • попытка повысить версию базы при активных соединениях;
  • конфликт транзакций между контекстами.

Сценарий многовкладочного удаления

При удалении базы в одной вкладке:

  • другие вкладки продолжают работать до момента получения сигнала блокировки;
  • после этого IndexedDB инициирует ожидание закрытия соединений;
  • удаление завершается только после освобождения всех блокировок.

Поведение при версии базы данных

Удаление и закрытие тесно связаны с системой версий IndexedDB.

Закрытие перед изменением версии

При повышении версии базы Dexie автоматически инициирует процесс versionchange, в ходе которого:

  • старые соединения блокируются;
  • транзакции завершаются;
  • требуется закрытие старых экземпляров.

Если экземпляр не закрыт, может возникнуть блокировка:

db.on('versionchange', () => {
    db.close();
});

Автоматическое закрытие при конфликте версии

При попытке открыть базу с новой версией в другом контексте:

  • старые соединения получают сигнал;
  • они должны быть закрыты вручную;
  • иначе новая версия не активируется.

Удаление базы во время работы приложения

Удаление базы во время активной работы требует строгого контроля состояния.

Корректная последовательность

  1. Завершение всех транзакций;
  2. Остановка фоновых процессов;
  3. Закрытие соединения;
  4. Удаление базы.
await db.transaction('rw', db.table, async () => {
    // завершение логики
});

db.close();
await Dexie.delete('myDatabase');

Ошибочные сценарии

Нарушение порядка приводит к:

  • утечкам соединений IndexedDB;
  • невозможности удалить базу до перезагрузки страницы;
  • зависанию транзакций в состоянии ожидания.

Повторное создание базы после удаления

После удаления база считается полностью уничтоженной. Повторное создание происходит как новая инициализация:

await Dexie.delete('myDatabase');

const db = new Dexie('myDatabase');
db.version(1).stores({
    users: '++id,name'
});

await db.open();

Особенность заключается в том, что:

  • отсутствуют старые миграции;
  • схема создаётся с нуля;
  • все индексы пересчитываются заново.

Ошибки и исключения при закрытии и удалении

Частые ошибки

InvalidStateError Возникает при попытке работы с базой после закрытия.

DatabaseDeleteBlocked Появляется при активных соединениях в других вкладках.

QuotaExceededError (косвенно) Может проявляться после некорректного освобождения ресурсов и последующих операций записи.

Обработка ошибок удаления

try {
    db.close();
    await Dexie.delete('myDatabase');
} catch (e) {
    console.error('Ошибка удаления базы', e);
}

Поведение Dexie при повторном открытии после удаления

Если попытаться открыть базу сразу после удаления:

await Dexie.delete('myDatabase');

await db.open();

поведение зависит от браузера:

  • база создаётся заново автоматически;
  • либо требуется повторная инициализация схемы перед открытием;
  • возможны задержки из-за асинхронного освобождения ресурсов IndexedDB.

Управление жизненным циклом базы через закрытие и удаление

Закрытие и удаление формируют полный цикл управления состоянием хранения данных:

  • open() создаёт активное соединение;
  • close() завершает работу экземпляра;
  • delete() уничтожает физическое хранилище.

Системная логика Dexie строится вокруг того, что закрытие всегда предшествует удалению, а удаление всегда означает полное уничтожение состояния без возможности восстановления через API IndexedDB.