Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Транзакция
Транзакция является последовательностью операций, выполненных как одна логическая единица работы. Он демонстрирует общие свойства ACID (атомарность, согласованность, изоляция, устойчивость) транзакций баз данных:
- Атомарность: транзакция должна быть атомарной единицей работы. Другими словами, либо выполняются все изменения данных, либо не выполняется ни одно из них.
- Согласованность. По завершении транзакция должна оставить все данные в согласованном состоянии. Все внутренние структуры данных должны быть правильными в конце транзакции.
- Изоляция: изменения, внесенные параллельными транзакциями, должны быть изолированы от изменений, внесенных другими параллельными транзакциями. Уровень изоляции, используемый для операции в ITransaction , определяется IReliableState , выполняющей операцию.
- Устойчивость: после завершения транзакции его эффекты постоянно сохраняются в системе. Изменения сохраняются даже в случае системного сбоя.
Уровни изоляции
Уровень изоляции определяет степень изоляции транзакции от изменений, внесенных другими транзакциями. Существует два уровня изоляции, поддерживаемые в надежных коллекциях:
Повторяемое чтение: Указывает, что выражения не могут считывать данные, которые были изменены, но еще не зафиксированы другими транзакциями, и что другие транзакции не могут изменять данные, которые были считаны текущей транзакцией, пока текущая транзакция не завершится.
- Преимущества чтения повторяемых транзакций
- Меньше использование памяти, чем в транзакциях моментальных снимков
- Обеспечивает согласованный возврат значений для нескольких чтений в определённое время
- Рекомендации по чтению повторяемых транзакций:
Записи блокируются при активном чтении данных
Операции чтения также блокируются во время активной записи данных.
- Преимущества чтения повторяемых транзакций
Моментальный снимок: указывает, что данные, читаемые любой инструкцией в транзакции, являются транзакционно согласованной версией данных, которые существовали в начале транзакции. Транзакция может распознавать только изменения данных, которые были зафиксированы до первого чтения транзакции. Изменения данных, внесенные другими транзакциями после начала текущей транзакции, не видны выражениям, выполняемым в текущей транзакции.
Результатом является то, что инструкции в транзакции получают моментальный снимок зафиксированных данных, как это существовало в начале транзакции. Снимки являются согласованными в надёжных коллекциях.
- Преимущества транзакций в режиме моментальных снимков:
- Позволяет записывать данные, даже если значение было прочитано в незафиксированной транзакции
- Рекомендации по транзакциям моментальных снимков:
- Длительные транзакции моментальных снимков могут привести к большому объему памяти для службы, так как дополнительные значения перемещаются в память для поддержания изоляции моментальных снимков
- Различные транзакции, в зависимости от времени создания моментального снимка, могут возвращать разные значения для данных чтения.
- Преимущества транзакций в режиме моментальных снимков:
Надежные коллекции автоматически определяют уровень изоляции для конкретной операции чтения в зависимости от типа операции и роли реплики на момент создания транзакции. Ниже приведена таблица, показывающая настройки уровня изоляции по умолчанию для операций с надежным словарем и очередью.
| Операция \ Роль | Первичный | Вторичный |
|---|---|---|
| Чтение отдельной сущности | Повторяемое чтение | Снимок |
| Перечисление, подсчёт | Снимок | Снимок |
Примечание.
Примеры основных операций с одной сущностью: IReliableDictionary.TryGetValueAsync, IReliableQueue.TryPeekAsync.
Надежный словарь и Надежная очередь поддерживают чтение собственных записей. Другими словами, любая запись в транзакции будет видна для следующей операции чтения, принадлежащей той же транзакции.
Пример повторяемого поведения чтения
В этом примере видно, что T2 не может получить блокировку на K1 до тех пор, пока T1 не зафиксирует, так как T1 в данный момент удерживает блокировку чтения на ключе.
Пример поведения снимка
В этом примере видно, что, несмотря на то, что T2 обновил значение K1 до V6, T2 по-прежнему перечисляет K1 как V1, при этом зная о собственном изменении K2. T3 не затрагивается, так как он считывает ключи, которые не имеют текущих блокировок записи.
Замки
В Надежных коллекциях все транзакции реализуют строгую двухфазную блокировку: транзакция не освобождает блокировки, которые она приобрела, пока транзакция не завершится либо прерыванием, либо фиксацией.
Надежный словарь использует блокировку на уровне строк для всех операций с одной сущностью.
Надежная очередь жертвует параллелизмом ради обеспечения строгого транзакционного свойства FIFO.
В надёжной очереди используются блокировки уровня операций, позволяющие одновременно использовать одну транзакцию с TryPeekAsync и/или TryDequeueAsync, и одну транзакцию с EnqueueAsync.
Обратите внимание, что для сохранения FIFO, если TryPeekAsync или TryDequeueAsync когда-либо обнаружат, что надежная очередь пуста, они также заблокируют EnqueueAsync.
Операции записи всегда устанавливают эксклюзивные блокировки. Для операций чтения блокировка зависит от нескольких факторов:
- Любая операция чтения, выполненная с использованием изоляции моментальных снимков, не требует блокировок.
- Любая повторяемая операция чтения по умолчанию принимает общие блокировки.
- Однако для любой операции чтения, поддерживающей повторяющееся чтение, пользователь может попросить блокировку обновления вместо общей блокировки. Блокировка обновления — это асимметричная блокировка, используемая для предотвращения распространенной взаимоблокировки, которая возникает, когда несколько транзакций блокируют ресурсы для потенциальных обновлений в дальнейшем.
Матрица совместимости блокировки приведена в следующей таблице:
| Запрос \ Разрешено | Отсутствует | Общее | Обновление | Исключительный |
|---|---|---|---|---|
| Общее | Нет конфликтов | Нет конфликтов | Конфликт | Конфликт |
| Обновление | Нет конфликтов | Нет конфликтов | Конфликт | Конфликт |
| Исключительный | Нет конфликтов | Конфликт | Конфликт | Конфликт |
Аргумент времени ожидания в API Надежных коллекций используется для обнаружения взаимоблокировки. Например, две транзакции (T1 и T2) пытаются считывать и обновлять K1. Они могут взаимоблокироваться, потому что в конечном итоге оба имеют общую блокировку.
В этом случае время ожидания одной или обеих операций истечет. В этом сценарии блокировка обновления может предотвратить такую взаимную блокировку.