Шаблон компенсирующих транзакций

Azure

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

Контекст и проблема

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

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

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

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

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

Решение

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

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

Ниже приведены два важных аспекта:

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

Этот подход похож на стратегию Сагаса, которая обсуждается в блоге Клеменса Ватерса.

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

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

Проблемы и рекомендации

Рассмотрим следующие моменты, когда вы решите, как реализовать этот шаблон:

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

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

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

  • Инфраструктура, обрабатывающая шаги, должна соответствовать следующим критериям:

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

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

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

  • Логика повторных попыток, которая более прощает, чем обычно, может помочь свести к минимуму сбои, которые активируют компенсирующую транзакцию. Если шаг в операции, реализующей итоговую согласованность, завершается сбоем, попробуйте обработать сбой как временное исключение и повторить шаг. Остановите операцию и инициируйте компенсирующую транзакцию только в том случае, если шаг завершается сбоем или не может быть восстановлен.

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

Когда следует использовать этот шаблон

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

Проектирование рабочей нагрузки

Архитектор должен оценить, как шаблон компенсации транзакций можно использовать в проектировании рабочей нагрузки для решения целей и принципов, описанных в основных принципах платформы Azure Well-Architected Framework. Например:

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

- Критически важные потоки RE:02
- Аварийное восстановление RE:09

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

Пример

Клиенты используют веб-сайт путешествия для книги маршрутов. Один маршрут может состоять из ряда рейсов и отелей. Клиент, который отправляется из Сиэтла в Лондон, а затем в Париж может выполнить следующие действия при создании маршрута:

  1. Забронировать место в рейсе F1 из Сиэтла в Лондон.
  2. Забронировать место в рейсе F2 из Лондона в Париж.
  3. Забронировать место в рейсе F3 из Парижа в Сиэтл.
  4. Забронировать номер в отеле H1 в Лондоне.
  5. Забронировать номер в отеле H2 в Париже.

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

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

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

Схема, демонстрирующая шаги по созданию маршрута. Также показаны шаги компенсирующей транзакции, отменяющей маршрут.

Примечание.

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

Во многих бизнес-решениях сбой одного шага не всегда требует отката системы с помощью компенсирующей транзакции. Например, рассмотрим сценарий веб-сайта путешествий. Предположим, клиент книги рейсы F1, F2 и F3, но не могут зарезервировать номер в отеле H1. Предпочтительнее предложить клиенту номер в другом отеле в одном городе, а не отменять рейсы. Клиент по-прежнему может решить отменить. В этом случае компенсирующая транзакция выполняется и отменяет резервирование для рейсов F1, F2 и F3. Но клиент должен принять это решение, а не систему.

Следующие шаги

  • Data Consistency Primer (Руководство по обеспечению согласованности данных). Шаблон компенсирующей транзакции часто используется для отмены операций, реализующих модель итоговой согласованности. Этот праймер предоставляет сведения о преимуществах и компромиссах конечной согласованности.
  • Шаблоны Идемпотентности. В компенсирующей транзакции лучше всего использовать идемпотентные команды. В этой записи блога описываются факторы, которые следует учитывать при реализации идемпотентности.
  • Шаблон диспетчера агентов планировщика. В этой статье описывается, как реализовать устойчивые системы, выполняющие бизнес-операции, использующие распределенные службы и ресурсы. В этих системах иногда требуется использовать компенсирующую транзакцию для отмены работы, выполняемой операцией.
  • Шаблон повторов. Компенсирующие транзакции могут быть вычислительными. Вы можете попытаться свести к минимуму их использование с помощью шаблона повторных попыток для реализации эффективной политики повторных попыток неудачных операций.
  • Шаблон распределенных транзакций Saga. В этой статье объясняется, как использовать шаблон Saga для управления согласованностью данных в микрослужбах в сценариях распределенных транзакций. Шаблон Saga обрабатывает восстановление сбоев с помощью компенсирующих транзакций.
  • Шаблон каналов и фильтров. В этой статье описывается шаблон каналов и фильтров, который можно использовать для разложения сложной задачи обработки в ряд повторно используемых элементов. Шаблон каналов и фильтров можно использовать с шаблоном компенсирующих транзакций в качестве альтернативы реализации распределенных транзакций.
  • Разработка с учетом возможности самовосстановления. В этом руководстве объясняется, как разрабатывать приложения самовосстановления. Вы можете использовать компенсирующие транзакции в рамках подхода самовосстановления.