# Управление данными в микросервисах ## Навигация - [🏠 Главная страница курса](../../../README.md) - [📚 Модуль 2](../README.md) --- ## База данных на сервис **Принцип:** Каждый микросервис имеет собственную базу данных. ### Преимущества: - Независимость данных - Разные типы БД для разных задач - Независимое масштабирование ### Недостатки: - Сложность транзакций - Проблемы с консистентностью - Дублирование данных ## Паттерны управления данными ### 1. Saga Pattern **Определение:** Паттерн для управления распределенными транзакциями. #### Choreography Saga ```java // Order Service public class OrderService { public void createOrder(CreateOrderRequest request) { Order order = new Order(request); orderRepository.save(order); // публикуем событие eventPublisher.publish(new OrderCreatedEvent(order.getId(), request.getItems())); } } // Inventory Service @EventHandler public class InventoryEventHandler { public void handleOrderCreated(OrderCreatedEvent event) { try { inventoryService.reserveItems(event.getItems()); eventPublisher.publish(new ItemsReservedEvent(event.getOrderId())); } catch (InsufficientStockException e) { eventPublisher.publish(new OrderCancelledEvent(event.getOrderId())); } } } // Payment Service @EventHandler public class PaymentEventHandler { public void handleItemsReserved(ItemsReservedEvent event) { try { paymentService.processPayment(event.getOrderId()); eventPublisher.publish(new PaymentProcessedEvent(event.getOrderId())); } catch (PaymentFailedException e) { eventPublisher.publish(new OrderCancelledEvent(event.getOrderId())); } } } ``` #### Orchestration Saga ```java @Service public class OrderOrchestrator { public void processOrder(CreateOrderRequest request) { Order order = orderService.createOrder(request); try { // шаг 1: резервирование товаров inventoryService.reserveItems(order.getId(), request.getItems()); // шаг 2: обработка платежа paymentService.processPayment(order.getId(), request.getPayment()); // шаг 3: подтверждение заказа orderService.confirmOrder(order.getId()); } catch (Exception e) { // компенсирующие транзакции compensateOrder(order.getId()); } } private void compensateOrder(OrderId orderId) { try { inventoryService.releaseItems(orderId); paymentService.refundPayment(orderId); orderService.cancelOrder(orderId); } catch (Exception e) { // логирование ошибок компенсации } } } ``` ### 2. CQRS (Command Query Responsibility Segregation) **Определение:** Разделение команд и запросов. ```java // Command Side @Service public class OrderCommandService { public void createOrder(CreateOrderCommand command) { Order order = new Order(command); orderRepository.save(order); // обновляем read model orderReadModelService.updateReadModel(order); } } // Query Side @Service public class OrderQueryService { public OrderView getOrderView(OrderId orderId) { return orderReadModelRepository.findById(orderId); } public List getOrdersByCustomer(CustomerId customerId) { return orderReadModelRepository.findByCustomerId(customerId); } } ``` ### 3. Event Sourcing **Определение:** Хранение событий вместо состояния. ```java @Entity public class OrderEvent { private Long id; private String aggregateId; private String eventType; private String eventData; private LocalDateTime occurredAt; } @Service public class OrderEventStore { public void saveEvent(OrderEvent event) { eventRepository.save(event); } public List getEvents(String aggregateId) { return eventRepository.findByAggregateIdOrderByOccurredAt(aggregateId); } } @Service public class OrderProjectionService { public OrderView buildOrderView(String orderId) { List events = eventStore.getEvents(orderId); OrderView view = new OrderView(); for (OrderEvent event : events) { applyEvent(view, event); } return view; } } ``` ## Консистентность данных ### Типы консистентности: #### 1. Strong Consistency - Все узлы видят одинаковые данные - Сложно в распределенных системах - Высокая задержка #### 2. Eventual Consistency - Данные в итоге станут консистентными - Подходит для большинства случаев - Низкая задержка #### 3. Weak Consistency - Нет гарантий консистентности - Используется редко ### Паттерны для консистентности: #### 1. Two-Phase Commit (2PC) **Проблема:** Блокирующий протокол **Решение:** Использовать Saga вместо 2PC #### 2. Three-Phase Commit (3PC) **Улучшение:** Меньше блокировок **Проблема:** Все еще сложный #### 3. Consensus Algorithms - **Raft** — выбор лидера - **Paxos** — консенсус в распределенных системах