Транзакции внутри каждой операции

Idb-keyval — это легковесная обертка над IndexedDB, обеспечивающая удобный интерфейс для работы с ключами и значениями. Несмотря на простоту API, каждая операция внутри Idb-keyval выполняется с использованием транзакций IndexedDB. Понимание принципов транзакций позволяет более эффективно использовать библиотеку и правильно обрабатывать асинхронные операции.

Транзакция в контексте IndexedDB — это последовательность операций, которые выполняются атомарно. Атомарность гарантирует, что либо все изменения внутри транзакции применяются, либо ни одно не применяется при возникновении ошибки. В Idb-keyval каждая функция (get, set, del, clear, keys) оборачивает свою логику в транзакцию автоматически, что избавляет от необходимости создавать транзакции вручную для простых операций.


Типы транзакций в Idb-keyval

Idb-keyval использует два основных типа транзакций:

  1. readonly — транзакция только для чтения. Используется при вызове get и keys.

    • Обеспечивает высокую производительность, так как не блокирует запись.
    • Пример: получение значения по ключу не изменяет состояние базы, поэтому можно выполнять несколько операций параллельно.
  2. readwrite — транзакция для чтения и записи. Используется при вызовах set, del и clear.

    • Гарантирует, что операция записи завершится полностью или не произойдет вовсе при ошибке.
    • Блокирует другие транзакции записи до завершения, что предотвращает конфликтные изменения данных.
import { get, set } from 'idb-keyval';

// Пример использования readwrite транзакции внутри set
await set('username', 'Alice'); // автоматически создается readwrite транзакция

Поведение транзакций при ошибках

Транзакции Idb-keyval ведут себя согласно спецификации IndexedDB:

  • Если внутри транзакции возникает исключение, транзакция автоматически откатывается.
  • Промис, возвращаемый функцией Idb-keyval, будет отклонен с ошибкой, которую можно обработать через .catch или конструкцию try/catch с async/await.

Пример обработки ошибок:

import { set } from 'idb-keyval';

try {
    await set('settings', { theme: 'dark' });
} catch (error) {
    console.error('Ошибка записи в IndexedDB:', error);
}

Важно понимать, что транзакция охватывает только одну функцию. Если нужно выполнить несколько операций атомарно, стандартный Idb-keyval не предоставляет встроенного метода для объединения операций в одну транзакцию. Для этого потребуется работать напрямую с IndexedDB API.


Асинхронная природа транзакций

Все операции Idb-keyval возвращают промисы, так как транзакции IndexedDB асинхронные. Это обеспечивает:

  • Возможность последовательного выполнения операций с использованием await.
  • Корректную обработку результатов после завершения транзакции.

Пример последовательного выполнения:

import { set, get } from 'idb-keyval';

await set('theme', 'light'); // завершение write транзакции
const theme = await get('theme'); // новая readonly транзакция
console.log(theme); // 'light'

Даже если транзакции создаются автоматически, важно помнить, что каждая операция запускает отдельную транзакцию. Это означает, что между двумя вызовами set могут сработать другие операции IndexedDB в браузере.


Особенности транзакций при массовых операциях

Idb-keyval предоставляет функции clear и keys для работы с большим количеством данных.

  • clear запускает readwrite транзакцию и удаляет все пары ключ-значение.
  • keys использует readonly транзакцию для перебора всех ключей.

Для больших наборов данных транзакции могут быть длительными. В таких случаях важно учитывать:

  • Возможность блокировки других транзакций write.
  • Ограничения на время выполнения транзакции в браузерах (например, Firefox и Chrome могут автоматически откатывать слишком длинные транзакции).

Ключевые моменты

  • Каждая операция Idb-keyval выполняется внутри транзакции IndexedDB.
  • readonly используется для чтения, readwrite — для записи и удаления.
  • Ошибки внутри транзакции вызывают откат всех изменений и отклонение промиса.
  • Для объединения нескольких операций в одну транзакцию требуется прямое использование IndexedDB.
  • Асинхронный характер транзакций обеспечивает правильное последовательное выполнение и обработку результатов.
  • Массовые операции могут занимать больше времени и блокировать другие записи, что важно учитывать при проектировании приложений.

Эти принципы позволяют использовать Idb-keyval безопасно и эффективно, понимая, как транзакции влияют на атомарность, консистентность и производительность операций.