Транзакции и режимы блокировки в надежных коллекциях Azure Service Fabric

Транзакция

Транзакция является последовательностью операций, выполненных как одна логическая единица работы. Она имеет общие свойства ACID (атомарность, согласованность, изолированность, надежность) транзакций баз данных:

  • Атомарность. Транзакция должна быть атомарной единицей работы. Другими словами, должны выполняться либо все ее изменения данных, либо ни одно из них.
  • Согласованность. По завершении транзакция должна оставить все данные в согласованном состоянии. Все внутренние структуры данных должны быть правильными на момент завершения транзакции.
  • Изоляция. Изменения, выполняемые одной параллельной транзакцией, должны быть изолированы от изменений, выполняемых прочими параллельными транзакциями. Уровень изоляции для операций в ITransaction определяется интерфейсом IReliableState, выполняющим операцию.
  • Устойчивость. После завершения транзакции ее результаты постоянно сохраняются в системе. Изменения сохраняются даже в случае системного сбоя.

Уровни изоляции

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

  • Повторяющееся чтение. Указывает, какие операторы не могут считывать данные, которые были изменены, но еще не зафиксированы другими транзакциями, и что другие транзакции не могут изменять данные, считанные текущей транзакцией, до ее завершения.
  • Моментальный снимок. Указывает, что данные, считанные любым оператором в транзакции, согласованы с версией данных, которые существовали в начале транзакции. Транзакция может распознать только те изменения данных, которые были зафиксированы до ее начала. Инструкции, выполняемые текущей транзакцией, не видят изменений данных, произведенных другими транзакциями после запуска текущей транзакции. Это похоже на то, как если бы инструкции в транзакции получили снимок данных, зафиксированных на момент начала транзакции. Моментальные снимки согласованы между надежными коллекциями.

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

Операция \ Роль Первичная Вторичная
Операция чтения одной сущности Повторяющаяся операция чтения Моментальный снимок
Перечисление, подсчет Моментальный снимок Моментальный снимок

Примечание

Распространенные примеры операций с одной сущностью: IReliableDictionary.TryGetValueAsync, IReliableQueue.TryPeekAsync.

Надежный словарь и надежная очередь поддерживают мгновенную целостность данных (Read Your Writes, RYW). Другими словами, каждая операция записи в рамках одной транзакции будет видна для последующей операции чтения, которая выполняется в рамках той же транзакции.

Блокировки

В надежных коллекциях все транзакции реализуют строгую двухэтапную блокировку: транзакция не снимает свои установленные блокировки, пока она не завершится прерыванием или фиксацией.

Надежный словарь использует блокировку уровня строки для всех операций с одной сущностью. Надежная очередь поступается параллелизмом ради строгого соблюдения транзакционного свойства FIFO. Надежная очередь использует блокировки уровня операции, позволяя одновременно выполнять одну транзакцию с TryPeekAsync и (или) TryDequeueAsync и одну транзакцию с EnqueueAsync. Обратите внимание, что если TryPeekAsync или TryDequeueAsync когда-либо обнаружит, что надежная очередь пуста, то для сохранения логики FIFO также заблокирует EnqueueAsync.

Операции записи всегда используют монопольные блокировки. Для операций чтения блокировка зависит от нескольких факторов:

  • В операциях чтения, выполняемых с уровнем изоляции "Снимок", блокировки не используются.
  • В повторяющихся операциях чтения используются совмещаемые блокировки (по умолчанию).
  • Тем не менее, для любой операции чтения, поддерживающей повторяющееся чтение, вместо совмещаемой блокировки пользователь может запросить блокировку изменений. Блокировка изменений является асимметричной блокировкой, которая используется для предотвращения распространенной формы взаимоблокировки. Взаимоблокировка возникает, когда несколько транзакций блокируют ресурсы для возможного обновления в будущем.

Ниже приведена таблица совместимости блокировок.

Запрос \ Предоставлено Нет Совмещаемая блокировка Update Монопольная блокировка
Совмещаемая блокировка Нет конфликтов Нет конфликтов Conflict Conflict
Update Нет конфликтов Нет конфликтов Conflict Conflict
Монопольная блокировка Нет конфликтов Conflict Conflict Conflict

В API надежных коллекций для обнаружения взаимоблокировок используется аргумент времени ожидания. Например, две транзакции (Т1 и Т2) пытаются считать и изменить К1. Существует вероятность возникновения взаимоблокировки, поскольку в обеих транзакциях используется совмещаемая блокировка. В этом случае время ожидания истечет для одной или обеих операций. В этом сценарии блокировка обновления может предотвратить такую взаимоблокировку.

Дальнейшие действия