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

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

Транзакции и конфликт данных

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

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

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

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

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

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

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

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

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

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

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

В Mobile/Web 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 использует оптимистические и пессимистические элементы управления параллелизмом для разрешения конфликтов.

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

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

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

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