Распределенные транзакции (Distributed Transactions) — это транзакции, которые охватывают несколько ресурсов (например, базы данных, очереди сообщений или микросервисы), расположенных на разных серверах или в разных системах. Реализация распределенных транзакций требует координации между этими ресурсами, чтобы обеспечить атомарность (все или ничего), согласованность, изоляцию и долговечность (ACID).
Двухфазный коммит — это протокол, который гарантирует, что все участники транзакции либо зафиксируют изменения, либо откатят их. Он состоит из двух фаз:
Пример:
// Координатор (Transaction Manager)
public class TransactionManager {
public boolean prepare(ResourceManager resource) {
return resource.prepare();
}
public void commit(ResourceManager resource) {
resource.commit();
}
public void rollback(ResourceManager resource) {
resource.rollback();
}
}
// Участник (Resource Manager)
public class ResourceManager {
public boolean prepare() {
// Логика подготовки
return true; // или false, если подготовка не удалась
}
public void commit() {
// Логика фиксации
}
public void rollback() {
// Логика отката
}
}
Преимущества:
Недостатки:
Saga — это паттерн для управления распределенными транзакциями в микросервисной архитектуре. Вместо использования синхронного 2PC, Saga разбивает транзакцию на последовательность локальных транзакций, каждая из которых компенсируется в случае ошибки.
Пример:
// Сервис A
public class ServiceA {
public void execute() {
// Логика выполнения
}
public void compensate() {
// Логика компенсации
}
}
// Сервис B
public class ServiceB {
public void execute() {
// Логика выполнения
}
public void compensate() {
// Логика компенсации
}
}
// Оркестратор Saga
public class SagaOrchestrator {
public void executeSaga() {
try {
new ServiceA().execute();
new ServiceB().execute();
} catch (Exception e) {
new ServiceB().compensate();
new ServiceA().compensate();
}
}
}
Преимущества:
Недостатки:
В этом подходе система допускает временную несогласованность данных, но гарантирует, что в конечном итоге все данные будут согласованы. Это часто используется в системах, основанных на событиях (event-driven architecture).
Пример:
// Сервис A
public class ServiceA {
public void publishEvent(Event event) {
// Публикация события
}
}
// Сервис B
public class ServiceB {
@EventListener
public void handleEvent(Event event) {
// Обработка события
}
}
Преимущества:
Недостатки:
XA — это стандарт для распределенных транзакций, который поддерживается многими базами данных и Java EE-серверами. Он использует двухфазный коммит для координации транзакций.
Пример:
// Использование XA в Java EE
@Stateless
public class XAService {
@Resource
private UserTransaction userTransaction;
@PersistenceContext(unitName = "primary")
private EntityManager entityManager;
public void execute() {
try {
userTransaction.begin();
entityManager.persist(new User("John"));
userTransaction.commit();
} catch (Exception e) {
userTransaction.rollback();
}
}
}
Преимущества:
Недостатки:
Реализация распределенных транзакций зависит от требований системы. Двухфазный коммит (2PC) обеспечивает строгую согласованность, но может быть медленным. Паттерн Saga подходит для микросервисов, но требует реализации компенсаций. Согласованность в конечном счете (Eventual Consistency) обеспечивает высокую производительность, но допускает временную несогласованность. XA-транзакции подходят для Java EE-приложений, но сложны в настройке. Выбор подхода зависит от архитектуры системы и требований к согласованности.