Сериализация и изоляция транзакций

На этой странице описывается конфликт транзакционных данных, сериализуемость и изоляция. Примеры кода транзакций см. в разделе «Транзакции и пакетная запись» .

Транзакции и конкуренция данных

Для успешного завершения транзакции документы, извлеченные операциями чтения, должны оставаться неизменными операциями вне транзакции. Если другая операция попытается изменить один из этих документов, эта операция вступит в состояние конфликта данных с транзакцией.

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

Cloud Firestore разрешает конфликт данных, задерживая или завершая сбоем одну из операций. Клиентские библиотеки Cloud Firestore автоматически повторяют транзакции, которые были прерваны из-за конфликта данных. После конечного числа повторных попыток транзакция завершается сбоем и возвращается сообщение об ошибке:

ABORTED: Too much contention on these documents. Please try again.

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

  • Мобильные/веб-SDK используют оптимистичные средства управления параллелизмом.

  • Библиотеки клиента сервера используют пессимистичные элементы управления параллелизмом.

Конфликт данных в мобильных/веб-SDK

Мобильные/веб-SDK (платформы Apple, Android, Web, C++) используют оптимистичные средства управления параллелизмом для разрешения конфликтов данных.

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

Мобильные и веб-SDK используют оптимистичный контроль параллелизма, поскольку они могут работать в средах с высокой задержкой и ненадёжным сетевым подключением. Блокировка документов в среде с высокой задержкой приведёт к слишком большому количеству сбоев из-за конфликтов данных.

В мобильных/веб-SDK транзакция отслеживает все документы, прочитанные внутри неё. Транзакция завершает операции записи только в том случае, если ни один из этих документов не изменился во время выполнения транзакции. Если какой-либо документ изменился, обработчик транзакций повторяет транзакцию. Если транзакция не может получить корректный результат после нескольких попыток, транзакция завершается ошибкой из-за конфликта данных.

Конфликт данных в клиентских библиотеках сервера

Клиентские библиотеки сервера (C#, Go, Java, Node.js, PHP, Python, Ruby) используют пессимистичные средства управления параллелизмом для разрешения конфликтов данных.

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

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

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

Когда транзакция блокирует документ, другие операции записи должны ждать, пока транзакция снимет блокировку. Транзакции устанавливают блокировки в хронологическом порядке.

Сериализуемая изоляция

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

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

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

Сериализуемая изоляция определяет наивысший уровень изоляции. Сериализуемая изоляция означает, что:

  • Можно предположить, что база данных выполняет транзакции последовательно.
  • На транзакции не влияют незафиксированные изменения в параллельных операциях.

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

Cloud Firestore гарантирует сериализуемую изоляцию транзакций. Транзакции в Cloud Firestore сериализуются и изолируются по времени фиксации.

Сериализуемая изоляция по времени фиксации

Cloud Firestore назначает каждой транзакции время фиксации, которое представляет собой определённый момент времени. Когда Cloud Firestore фиксирует изменения транзакции в базе данных, можно предположить, что все операции чтения и записи в рамках транзакции выполняются точно в момент фиксации.

Фактическое выполнение транзакции требует определённого времени. Выполнение транзакции начинается до момента фиксации, и выполнение нескольких операций может перекрываться. Cloud Firestore поддерживает сериализуемую изоляцию и гарантирует следующее:

  • Cloud Firestore фиксирует транзакции в порядке времени фиксации.
  • Cloud Firestore изолирует транзакции от параллельных операций с более поздним временем фиксации.

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

Изоляция внутри транзакции

Изоляция транзакций также применяется к операциям записи внутри транзакции. Запросы и операции чтения внутри транзакции не видят результаты предыдущих операций записи внутри этой транзакции. Даже если вы изменяете или удаляете документ внутри транзакции, все операции чтения документов в этой транзакции возвращают версию документа на момент фиксации, до операций записи в транзакции. Операции чтения ничего не возвращают, если документ в тот момент не существовал.

Проблемы с конкуренцией данных

Дополнительную информацию о конфликтах данных и способах их разрешения можно найти на странице устранения неполадок .