1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/mirrors-cqengine

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
TransactionIsolation.md 9.4 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 28.11.2024 02:48 973f548

Транзакционная изоляция в CQEngine (MVCC)

Начиная с версии CQEngine 2.0, поддерживается многоверсионное управление параллельным доступом (MVCC), предоставляя изоляцию транзакций READ_COMMITTED «из коробки» через класс TransactionalIndexedCollection.

Транзакция состоит из набора объектов, которые должны быть добавлены в коллекцию, и набора объектов, которые необходимо удалить из коллекции. Любой из этих наборов может быть пустым, поэтому это поддерживает массовое атомарное добавление и атомарное удаление объектов из коллекции. Но если оба набора непустые, то это позволяет массово атомарно заменять объекты в коллекции.

Потоки чтения гарантированно видят согласованную версию коллекции, где транзакции были применены полностью. Чтения не блокируются, однако записи сериализуются. При использовании этой функции также необходимо вызывать close() для ResultSets.

Пример использования (исходный код здесь):

// Создаём примеры автомобилей...
Car car1 = CarFactory.createCar(1); // "Ford Fusion"
Car car2 = CarFactory.createCar(2); // "Ford Taurus"
Car car3 = CarFactory.createCar(3); // "Honda Civic"
Car car4 = CarFactory.createCar(4); // "Honda Accord"

// Мы будем хранить автомобили в TransactionalIndexedCollection, которая обеспечивает поддержку MVCC...
IndexedCollection<Car> cars = new TransactionalIndexedCollection<Car>(Car.class);

// ===== Примеры изменения коллекции с использованием транзакций MVCC... =====

// Добавляем 4 автомобиля за одну транзакцию...
cars.addAll(asList(car1, car2, car3, car4));

// Удаляем 2 автомобиля за одну транзакцию...
cars.removeAll(asList(car3, car4));

// Заменяем 1 автомобиль на 2 других автомобиля за одну транзакцию...
cars.update(asList(car2), asList(car3, car4));

// ===== Примеры запросов к коллекции с использованием транзакций MVCC... =====

// Извлекаем с изоляцией транзакций READ_COMMITTED...
ResultSet<Car> results = cars.retrieve(equal(Car.MANUFACTURER, "Ford"));
try {
    for (Car car : results) {
        System.out.println(car); // выводит автомобиль 1 ("Ford Fusion")
    }
}
finally {
    results.close(); // ..закрываем ResultSet после завершения чтения!
}

Атомарная замена одного и того же объекта

Обратите внимание, что если вы хотите заменить существующий объект новой версией того, что фактически является тем же объектом, вам нужно будет добавить скрытое поле версии к вашему объекту, как описано в JavaDoc.

Транзакционная изоляция без MVCC

Этот раздел в основном относится к версиям CQEngine до 2.0, которые не включали TransactionalIndexedCollection и поддержку MVCC. Однако информация всё ещё верна и может быть полезна для понимания внутренней модели параллелизма CQEngine, особенно при использовании одной из других, нетранзакционных реализаций IndexedCollection.

CQEngine по умолчанию предоставляет неблокирующие чтения.

В зависимости от типов запросов, которые могут выполняться во время модификации коллекции, CQEngine по умолчанию обеспечивает уровень изоляции транзакций, который находится где-то между READ_COMMITTED и READ_UNCOMMITTED. Но CQEngine поддерживает более высокие уровни изоляции, чем этот по умолчанию, для приложений, которым это необходимо. Изоляцией транзакций можно управлять для каждого запроса отдельно.

В этом разделе обсуждается:

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

Гарантии согласованности

Модель согласованности CQEngine заключается в том, что объекты всегда добавляются и удаляются из IndexedCollection и индексов с волатильной семантикой.

Это гарантирует, что:

  • Когда методы IndexedCollection.add/remove/addAll и т. д. возвращаются, данные были зафиксированы в коллекции и во всех индексах.
  • Любые запросы, выполненные после возврата этих методов, гарантированно увидят полностью согласованное представление (READ_COMMITTED) объектов во всех структурах данных.

Поэтому добавление или удаление одного объекта во время выполнения запросов не требует блокировки. Текущие запросы будут видеть изоляцию транзакций READ_COMMITTED по отношению к вставке или удалению одного объекта.

Однако запросы, выполняемые во время пакетных или нескольких модификаций коллекции, не покрываются этой гарантией согласованности. Эти запросы могут увидеть подмножество модификаций, сделанных во время их выполнения (READ_UNCOMMITTED).

Изоляция READ_COMMITTED для пакетных модификаций

Приложения могут использовать ReadWriteLock (для сценариев записи всегда) или ReadWriteUpdateLock (для чтения и потенциально записи) для получения транзакционной изоляции или READ_COMMITTED с CQEngine.

Приложения должны кэшировать блокировку в том же месте, где находится IndexedCollection, которую она будет защищать, и использовать её следующим образом, чтобы обеспечить изоляцию READ_COMMITTED только при необходимости:

  • Методы, которые будут выполнять пакетные или множественные модификации, которые должны рассматриваться как атомарная транзакция потоками чтения, должны:
    • Получить блокировку записи перед изменением коллекции и снять её, когда завершится последнее изменение.
  • Методы, выполняющие запросы, требующие изоляции READ_COMMITTED, должны:
    • Получить блокировку чтения перед этим и удерживать её до тех пор, пока они полностью не закончат итерацию по ResultSet.
  • Методы, выполняющие запросы, которые были бы совместимы с изоляцией READ_UNCOMMITTED, должны:
    • Выполнять чтение без получения блокировки чтения.
  • Приложения, которые выполняют только однократные вставки/удаления объектов за раз или многократные вставки/удаления, которые не должны быть транзакционными:
    • Не должны использовать какую-либо блокировку.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/mirrors-cqengine.git
git@api.gitlife.ru:oschina-mirror/mirrors-cqengine.git
oschina-mirror
mirrors-cqengine
mirrors-cqengine
master