Как реализовать распределенные транзакции в Java-приложении?

«Как реализовать распределенные транзакции в Java-приложении?» — вопрос из категории Архитектура, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Распределенные транзакции координируют операции над несколькими ресурсами (БД, очереди) в рамках единой ACID-транзакции.

Основные подходы в Java:

  1. JTA (Java Transaction API) с XA-протоколом:

    • Используется для транзакций, охватывающих несколько XA-совместимых ресурсов (например, две разные БД).
    • Координатором выступает JTA-провайдер (Atomikos, Bitronix).
      // Пример объявления в Spring
      @Transactional
      public void processOrder(Order order, Inventory inventory) {
      orderRepository.save(order); // Ресурс 1
      inventoryRepository.save(inventory); // Ресурс 2
      }
  2. Spring Transaction Management:

    • Упрощает декларативное управление транзакциями через @Transactional.
    • Для распределенных сценариев требуется настройка JTA-менеджера.

Проблемы и альтернативы:

  • Производительность: Двухфазный коммит (2PC) блокирует ресурсы до завершения, создавая нагрузку на координатор.
  • Сложность отказов: Координатор становится единой точкой отказа.
  • Современная альтернатива — Saga-паттерн:
    • Подходит для микросервисной архитектуры.
    • Длинная бизнес-транзакция разбивается на последовательность локальных транзакций.
    • Компенсирующие транзакции (Compensating Transactions) откатывают изменения при сбое.