Транзакции

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

Режимы транзакций

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

Также можно ослабить уровень изоляции, выставив значения ReadCommitted, ReadUncommitted и ReadStale при помощи соответствующей pragma:

  • Serializable Read Write — режим выполнения read/write транзакций с самым высоким уровнем изолированности; транзакции полностью изолируются друг от друга, каждая выполняется так, как будто транзакции выполняются последовательно;
  • Online Read Only — режим чтения последних актуальных на момент чтения данных. Нет repeatable reads. Есть возможность настройки Consistent reads / Inconsistent reads;
  • Stale Read Only — режим чтения данных с возможным отставанием (доли секунды). Consistent reads.

Реализация транзакций с помощью YQL

Реализованные конструкции YQL можно разделить на два класса: язык описания данных (DDL) и язык управления данными (DML).

Ниже перечислены возможности и ограничения поддержки YQL в YDB, которые могут быть неочевидны на первый взгляд и на которые стоит обратить внимание:

  • Допускаются multistatement transactions, то есть транзакции, состоящие из последовательности выражений YQL. При выполнении транзакции допускается взаимодействие с клиентской программой, иначе говоря, взаимодействие клиента с базой может выглядеть следующим образом:
BEGIN;
Выполнить SELECT;
Проанализировать результаты SELECT на клиенте;
...;
Выполнить UPDATE;
COMMIT

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

  • В YDB не поддерживается возможность смешивать DDL и DML запросы в одной транзакции. Традиционное понятие ACID транзакции применимо именно к DML запросам, то есть к запросам, которые меняют данные. DDL запросы должны быть идемпотентными, то есть повторяемы в случае ошибки. Если необходимо выполнить действие со схемой, то каждое из действий будет транзакционно, а набор действий - нет.
  • Реализация YQL в YDB использует механизм Optimistic Concurrency Control. На затронутые в ходе транзакции сущности ставятся оптимистичные блокировки, при завершении транзакции проверяется, что блокировки не были инвалидированы. Оптимистичность блокировок выливается в важное для пользователя свойство — в случае конфликта выигрывает транзакция, которая завершается первой. Конкурирующие транзакции завершатся с ошибкой Transaction locks invalidated.
  • Все изменения, производимые в рамках транзакции, накапливаются в памяти сервера базы данных и применяются в момент завершения транзакции. Если взятые блокировки не были инвалидированы, то все накопленные изменения применяются атомарно, если хотя бы одна блокировка была инвалидирована, то ни одно из изменений не будет применено. Описанная схема накладывает некоторые ограничения: объем изменений осуществляемых в рамках одной транзакции должен умещаться в память и транзакция "не видит" своих изменений.

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

SELECT ...;
....
SELECT ...;
UPDATE/REPLACE/DELETE ...;
COMMIT;

Подробнее про поддержку YQL в YDB можно прочитать в документации YQL.

Распределенные транзакции

Таблица в YDB может быть шардирована по диапазонам значений первичного ключа. Различные шарды таблицы могут обслуживаться разными серверами распределенной базы данных (в том числе расположенными в разных зонах доступности), а также могут независимо друг от друга перемещаться между серверами для перебалансировки или поддержания работоспособности шарда при отказах серверов или сетевого оборудования.

В YDB поддерживаются распределенные транзакции — такие транзакции, которые затрагивают более одного шарда одной или нескольких таблиц.