На этой странице описаны конфликты данных при транзакциях, сериализуемость и изоляция. Примеры кода для транзакций см. в разделе «Транзакции и пакетная запись» .
Транзакции и конфликты данных
Для успешного завершения транзакции документы, полученные в результате операций чтения, должны оставаться неизмененными операциями, находящимися вне этой транзакции. Если другая операция попытается изменить один из этих документов, она перейдет в состояние конфликта данных с транзакцией.
- Конфликт данных
- Когда две или более операций конкурируют за управление одним и тем же документом. Например, одна транзакция может требовать сохранения согласованности документа, в то время как параллельная операция пытается обновить значения полей этого документа.
Cloud Firestore разрешает конфликты данных, задерживая или прерывая одну из операций. Клиентские библиотеки Cloud Firestore автоматически повторяют транзакции, которые завершаются с ошибкой из-за конфликта данных. После конечного числа повторных попыток операция транзакции завершается с ошибкой и возвращает сообщение об ошибке:
ABORTED: Too much contention on these documents. Please try again.
При принятии решения о том, какую операцию следует завершить неудачей или отложить, поведение зависит от типа клиентской библиотеки.
Cloud Firestore можно настроить режим параллельного доступа: PESSIMISTIC или OPTIMISTIC . По умолчанию для стандартной версии используется режим PESSIMISTIC , а для корпоративной — OPTIMISTIC . Рекомендуется использовать PESSIMISTIC . Мобильные и веб-SDK работают независимо от этой настройки, поскольку они всегда эмулируют оптимистичный параллельный доступ.
В мобильных/веб-SDK используется оптимистичный контроль параллельного доступа.
В клиент-серверных библиотеках используется пессимистичный контроль параллельного доступа.
Конфликты данных в мобильных/веб-SDK
Мобильные и веб-SDK имитируют оптимистичные параллельные транзакции, используя предварительные условия записи для версий документов. Эта эмуляция происходит независимо от настроек режима параллельного доступа базы данных. Мобильные и веб-SDK не используют встроенную функцию транзакций , поэтому даже если режим параллельного доступа базы данных настроен на PESSIMISTIC , мобильные клиенты все равно будут вести себя оптимистично.
- Оптимистичные механизмы управления параллельным доступом
- Исходя из предположения, что конкуренция за данные маловероятна или что удержание блокировок базы данных неэффективно, оптимистичные транзакции не используют блокировки базы данных для предотвращения изменения данных другими операциями.
Мобильные/веб-SDK используют оптимистичный контроль параллельного доступа, поскольку они могут работать в средах с высокой задержкой и ненадежным сетевым соединением. Блокировка документов в условиях высокой задержки приведет к слишком большому количеству сбоев из-за конфликтов данных.
В мобильных/веб-SDK транзакция отслеживает все документы, которые вы читаете внутри транзакции. Транзакция завершает операции записи только в том случае, если ни один из этих документов не изменился во время выполнения транзакции. Если какой-либо документ изменился, обработчик транзакции повторяет транзакцию. Если транзакция не может получить корректный результат после нескольких повторных попыток, она завершается с ошибкой из-за конфликта данных.
Конфликты данных в клиентских библиотеках сервера
Клиент-серверные библиотеки (C#, Go, Java, Node.js, PHP, Python, Ruby) используют встроенную функцию транзакций , которая по умолчанию реализует пессимистический контроль параллельного доступа. Эти транзакции учитывают настройку режима параллельного доступа на уровне базы данных (обычно PESSIMISTIC ) и используют блокировки документов для предотвращения конфликтующих операций записи.
- Пессимистичные методы управления параллельным доступом
- Исходя из предположения о высокой вероятности конфликта данных, пессимистичные транзакции используют блокировки базы данных для предотвращения изменения данных другими операциями.
Клиент-серверные библиотеки используют пессимистичный подход к управлению параллельным доступом, поскольку предполагают низкую задержку и надежное соединение с базой данных.
В клиент-серверных библиотеках транзакции устанавливают блокировки на читаемые ими документы. Блокировка документа, установленная транзакцией, препятствует другим транзакциям, пакетной записи и нетранзакционной записи изменять этот документ. Транзакция снимает свои блокировки документов во время фиксации транзакции. Она также снимает свои блокировки, если истекает время ожидания или происходит сбой по какой-либо причине.
Когда транзакция блокирует документ, другие операции записи должны дождаться, пока транзакция снимет свою блокировку. Транзакции получают свои блокировки в хронологическом порядке.
Последовательная изоляция
Конфликты данных между транзакциями тесно связаны с уровнями изоляции базы данных. Уровень изоляции базы данных описывает, насколько хорошо система обрабатывает конфликты между параллельными операциями. Конфликты возникают из-за следующих требований к базе данных:
- Для проведения транзакций необходимы точные и согласованные данные.
- Для эффективного использования ресурсов базы данных выполняют операции параллельно.
В системах с низким уровнем изоляции операция чтения внутри транзакции может считывать неточные данные из незафиксированных изменений в параллельной операции.
Сериализуемая изоляция определяет наивысший уровень изоляции. Сериализуемая изоляция означает, что:
- Можно предположить, что база данных выполняет транзакции последовательно.
- На транзакции не влияют незафиксированные изменения в одновременно выполняемых операциях.
Эта гарантия должна сохраняться даже при параллельном выполнении базой данных множества транзакций. База данных должна внедрить механизмы контроля параллельного доступа для разрешения конфликтов, которые могли бы нарушить эту гарантию.
Cloud Firestore гарантирует сериализуемую изоляцию транзакций. Транзакции в Cloud Firestore сериализуются и изолируются во время фиксации.
Сериализуемая изоляция во время фиксации изменений
Cloud Firestore присваивает каждой транзакции время фиксации, которое представляет собой конкретный момент времени. Когда Cloud Firestore фиксирует изменения транзакции в базе данных, можно предположить, что все операции чтения и записи в рамках транзакции происходят точно в момент фиксации.
Фактическое выполнение транзакции занимает определённый промежуток времени. Выполнение транзакции начинается до момента подтверждения, и выполнение нескольких операций может перекрываться. Cloud Firestore поддерживает сериализуемую изоляцию и гарантирует, что:
- Cloud Firestore фиксирует транзакции в порядке времени подтверждения.
- Cloud Firestore изолирует транзакции от параллельных операций, обеспечивая более позднее время подтверждения.
В случае конфликтов данных между одновременно выполняемыми операциями Cloud Firestore использует оптимистический и пессимистический механизмы управления параллельным доступом для разрешения этих конфликтов.
Изоляция внутри транзакции
Изоляция транзакций также применяется к операциям записи внутри транзакции. Запросы и операции чтения внутри транзакции не видят результатов предыдущих операций записи внутри этой транзакции. Даже если вы изменяете или удаляете документ внутри транзакции, все операции чтения документа в этой транзакции возвращают версию документа на момент фиксации, до операций записи в транзакции. Операции чтения ничего не возвращают, если документ на тот момент не существовал.
Проблемы с конфликтами данных
Для получения более подробной информации о конфликтах данных и способах их устранения посетите страницу устранения неполадок .