Описание конкурентности

Завершено

Основная функция многопользовательских баз данных — параллелизм. Конкурентность использует блокировку и блокирование для обеспечения согласованности данных, когда множество пользователей обновляют и считывают данные одновременно. Например, из-за затрат на доставку все наши товары имеют увеличение цены на $5. В то же время из-за курсов валют все продукты подвержены уменьшению цен на 3%. Если эти обновления происходят точно в то же время, окончательная цена будет переменной, и вероятно, будет много ошибок. С помощью блокировки можно убедиться, что одно обновление завершится до начала другого.

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

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

Замечание

Полная детализация блокировки транзакций за пределами параллелизма связана с производительностью и не только зависит от кода, хотя хороший код работает лучше. Дополнительные сведения см. в руководстве по блокировке транзакций SQL Server и настройке версий строк. Дополнительные сведения о блокировке см. в документации по производительности SQL Server.

Оптимистическая конкуренция

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

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

Пессимистичный параллелизм

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

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

Изоляция снимка

SQL Server поддерживает пять уровней изоляции транзакций ,READ UNCOMMITTED , , SNAPSHOTREPEATABLE READа также SERIALIZABLEзадает для каждого сеансаSET TRANSACTION ISOLATION LEVEL. READ COMMITTED READ_COMMITTED_SNAPSHOT Отдельно — это параметр уровня базы данных (с наборомALTER DATABASE), который изменяет READ COMMITTED поведение уровня изоляции. В этом модуле мы сосредоточимся на этих двух параметрах базы данных, так как они определяют, используют ли транзакции по умолчанию READ COMMITTED пессимистичные блокировки или управление версиями строк.

  • При READ_COMMITTED_SNAPSHOT OFF использовании (по умолчанию для SQL Server) READ COMMITTED транзакции получают общие блокировки для строк, которые они считывают и удерживают их до завершения чтения. Это предотвращает большинство конфликтующих изменений в считываемых данных и является формой пессимистического параллелизма.
  • При READ_COMMITTED_SNAPSHOT ON использовании (по умолчанию для База данных SQL Azure и Управляемый экземпляр SQL Azure) READ COMMITTED транзакции используют управление версиями строк, хранящиеся в tempdb. Каждая инструкция видит последнюю зафиксированную версию каждой строки по состоянию на момент запуска этого оператора, поэтому читатели никогда не блокируют записи и записи никогда не блокируют средства чтения. Записи по-прежнему получают стандартные монопольные блокировки, поэтому одновременные записи в одну и ту же строку по-прежнему блокируют друг друга. Это форма оптимистического параллелизма для операций чтения, но обратите внимание на отсутствие автоматического обнаружения конфликтов во время фиксации для операций записи; это поведение относится к отдельному SNAPSHOT уровню изоляции.

Чтобы включить, выполните следующую READ_COMMITTED_SNAPSHOT команду:

ALTER DATABASE <db_name> SET READ_COMMITTED_SNAPSHOT ON;

Чтобы отключить его, выполните приведенные далее действия.

ALTER DATABASE <db_name> SET READ_COMMITTED_SNAPSHOT OFF;

Если база данных была изменена для включения фиксации моментального снимка чтения, любая транзакция, использующая уровень изоляции по умолчанию READ COMMITTED , использует управление версиями строк вместо общих блокировок чтения.

Замечание

Параметр READ_COMMITTED_SNAPSHOT базы данных влияет только на транзакции, выполняемые READ COMMITTED на уровне изоляции. Транзакции явно используют другие уровни изоляции (REPEATABLE READилиSERIALIZABLESNAPSHOT) не влияют на этот параметр.