Демистификация транзакционных границ микросервисов: методы и примеры кода

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

  1. Синхронная связь.
    Один из подходов — использовать синхронную связь между микрослужбами, при которой вызывающая служба ожидает ответа, прежде чем продолжить. Это обеспечивает согласованность транзакций в рамках одного запроса. Вот пример использования RESTful API:
# Service A calling Service B synchronously
response = requests.post('http://service-b/api/resource', data={'param': 'value'})
if response.status_code == 200:
    # Commit transaction
else:
    # Rollback transaction
  1. Асинхронная связь с конечной согласованностью.
    Другой метод – использовать асинхронную связь и достичь итоговой согласованности. Вызывающая служба публикует событие, указывающее желаемое действие, а другие службы подписываются на эти события и соответствующим образом обновляют свое состояние. Вот пример использования очередей сообщений:
# Service A publishing an event
message_queue.publish('resource_created', {'param': 'value'})
# Service B subscribing to the event and updating its state asynchronously
def event_handler(event):
    data = event.data
    # Update state in Service B
message_queue.subscribe('resource_created', event_handler)
  1. Координатор распределенных транзакций (DTC).
    Координатор распределенных транзакций действует как централизованный орган, который управляет транзакциями в нескольких микросервисах. Это обеспечивает атомарность и согласованность между участвующими службами. Вот пример использования протокола двухфазной фиксации:
# Service A initiating a distributed transaction
dtc.begin()
# Service A making changes
service_a.save_changes()
# Service B participating in the transaction
dtc.register(service_b)
# Service B making changes
service_b.save_changes()
# Service A and B committing the transaction
dtc.commit()
  1. Шаблон Saga.
    Шаблон Saga — это шаблон компенсирующих транзакций, который разбивает длительную транзакцию на последовательность более мелких локализованных транзакций. В случае сбоя на этапе выполняются компенсирующие действия для отмены внесенных на данный момент изменений. Вот пример:
# Saga orchestration in Service A
saga = Saga()
saga.add_step(service_a.create_resource, service_a.undo_create_resource)
saga.add_step(service_b.update_resource, service_b.undo_update_resource)
saga.add_step(service_c.delete_resource, service_c.undo_delete_resource)
saga.execute()

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