Files
sa-lessons/modules/module2/sections/04-data-management.md
Alexander Abakumov 15e744da49 Initial commit: Complete Software Architecture course with 11 modules
- Added comprehensive course structure with 11 modules
- Included theoretical content, practical examples, and tasks
- Multi-language code examples (Java, Rust, Node.js, Python)
- Detailed analysis of architectural approaches and trade-offs
- Complete caching strategies documentation
- Architecture examples from real-world systems (Twitter, Netflix, Uber)
- Structured navigation and learning path
- Ready for educational use
2025-09-09 22:08:07 +03:00

202 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Управление данными в микросервисах
## Навигация
- [🏠 Главная страница курса](../../../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<OrderView> 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<OrderEvent> getEvents(String aggregateId) {
return eventRepository.findByAggregateIdOrderByOccurredAt(aggregateId);
}
}
@Service
public class OrderProjectionService {
public OrderView buildOrderView(String orderId) {
List<OrderEvent> 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** — консенсус в распределенных системах