Taqsimlangan ma’lumotlar patternlari (Distributed Data Patterns)

02.07.2026 | Muallif: Jaxongir a.k.a | Kategoriya: Spring Boot | 24 daqiqa o'qish

Distributed data patterns - microservice yoki modullarga bo‘lingan system’da ma’lumotlar bir nechta joyda saqlanganda consistency, transaction, retry, event va failure muammolarini boshqarish usullari hisoblanadi.

Bu blok quyidagilarni o‘z ichiga oladi: SAGA orchestration vs choreography, Transactional Outbox + Debezium CDC, Idempotent Consumer, Distributed Locking, va Two-Phase Commit’dan qachon qochishni hal qiladi.


1. Muammo nimada?

Monolith’da bitta database bo‘lsa, transaction oddiy:

Order yaratildi
Payment yozildi
Stock kamaytirildi
Delivery yaratildi
        ↓
bitta database transaction

Kodda:

@Transactional
public void checkout() {
    orderRepository.save(order);
    paymentRepository.save(payment);
    stockRepository.decrease(productId);
    deliveryRepository.create(orderId);
}

Agar xato bo‘lsa:

rollback

Hammasi bitta database ichida qaytadi.


2. Distributed system’da muammo

Microservice architecture’da har service odatda o‘z database’iga ega:

order-service       → order_db
payment-service     → payment_db
inventory-service   → inventory_db
delivery-service    → delivery_db

Endi bitta @Transactional bilan hammasini boshqarib bo‘lmaydi.

Masalan checkout flow:

1. Order yaratish
2. Payment olish
3. Stock kamaytirish
4. Delivery yaratish

Agar 3-qadamda stock kamaytirish yiqilsa:

Order yaratildi
Payment olindi
Stock kamaymadi
Delivery yaratilmadi

System "yarim bajarilgan" holatda qoladi.

Distributed data patterns shuni boshqarish uchun kerak.


3. Muhim tushuncha: local transaction

Har service faqat o‘z database’ida transaction qila oladi.

order-service:
@Transactional
order_db ichida transaction

payment-service:
@Transactional
payment_db ichida transaction

inventory-service:
@Transactional
inventory_db ichida transaction

Lekin bularni bitta global transaction qilish murakkab va ko‘pincha yomon tanlov.

Shuning uchun distributed system’da ko‘proq quyidagi model ishlatiladi:

Local transaction
+ Event
+ Retry
+ Compensation
+ Idempotency
+ Observability

4. SAGA Pattern

SAGA - uzun biznes transaction’ni bir nechta kichik local transactionlarga bo‘lish patterni.

Har qadam:

local transaction bajaradi
keyingi qadamni chaqiradi yoki event chiqaradi
xato bo‘lsa compensation ishlaydi

Masalan order checkout:

Create Order
   ↓
Reserve Stock
   ↓
Take Payment
   ↓
Create Delivery
   ↓
Complete Order

Agar payment fail bo‘lsa:

Payment failed
   ↓
Release Stock
   ↓
Cancel Order

Bu yerda rollback database rollback emas. Bu compensating action deyiladi.


5. Compensation nima?

Compensation - oldin bajarilgan qadamni biznes jihatdan bekor qilish.

Misollar:

Amal

Compensation

Order yaratildi

Order cancel qilinadi

Stock reserve qilindi

Stock release qilinadi

Payment olindi

Refund qilinadi

Delivery yaratildi

Delivery cancel qilinadi

Bonus berildi

Bonus qaytarib olinadi

Muhim:

Compensation har doim real rollback emas. Masalan payment refund qilinsa, pul darhol qaytmasligi mumkin. Lekin biznes holat tuzatiladi.


6. SAGA ikki xil bo‘ladi

1. Choreography
2. Orchestration

7. SAGA Choreography

Choreography’da markaziy boshqaruvchi yo‘q. Har service event eshitadi va o‘z ishini qiladi.

Flow:

OrderCreatedEvent
        ↓
Inventory service stock reserve qiladi
        ↓
StockReservedEvent
        ↓
Payment service pul oladi
        ↓
PaymentCompletedEvent
        ↓
Delivery service delivery yaratadi
        ↓
DeliveryCreatedEvent
        ↓
Order service orderni CONFIRMED qiladi

Choreography example

order-service:
OrderCreatedEvent publish qiladi

inventory-service:
OrderCreatedEvent eshitadi
StockReservedEvent publish qiladi

payment-service:
StockReservedEvent eshitadi
PaymentCompletedEvent publish qiladi

delivery-service:
PaymentCompletedEvent eshitadi
DeliveryCreatedEvent publish qiladi

Kodda ko‘rinishi:

@Component
class InventoryOnOrderCreated {

    private final InventoryService inventoryService;
    private final ApplicationEventPublisher events;

    @EventListener
    public void on(OrderCreatedEvent event) {
        inventoryService.reserve(event.orderId(), event.items());

        events.publishEvent(new StockReservedEvent(
                event.orderId(),
                event.items()
        ));
    }
}

Choreography afzalliklari

loose coupling
markaziy coordinator yo‘q
service’lar mustaqilroq
event-driven architecture uchun tabiiy
kichik flowlarda yaxshi

Choreography kamchiliklari

flow qayerda tugashini tushunish qiyin
debug qilish murakkab
event chain ko‘payib ketadi
failure handling tarqalib ketadi
business process diagrammasi kodda aniq ko‘rinmaydi

Katta flow’da shunday bo‘lib ketadi:

OrderCreated → StockReserved → PaymentStarted → PaymentCompleted
→ DeliveryCreated → InvoiceGenerated → NotificationSent

Xato qayerda bo‘lganini topish qiyinlashadi.


8. SAGA Orchestration

Orchestration’da bitta markaziy orchestrator flow’ni boshqaradi.

Masalan:

OrderSagaOrchestrator
   ↓
InventoryService.reserve()
   ↓
PaymentService.charge()
   ↓
DeliveryService.create()
   ↓
OrderService.confirm()

Agar payment fail bo‘lsa:

OrderSagaOrchestrator
   ↓
InventoryService.release()
   ↓
OrderService.cancel()

Orchestration misol kod:

@Service
public class OrderSagaOrchestrator {

    private final InventoryClient inventoryClient;
    private final PaymentClient paymentClient;
    private final DeliveryClient deliveryClient;
    private final OrderService orderService;

    public void process(Long orderId) {
        try {
            inventoryClient.reserve(orderId);
            paymentClient.charge(orderId);
            deliveryClient.create(orderId);
            orderService.confirm(orderId);
        } catch (PaymentFailedException ex) {
            inventoryClient.release(orderId);
            orderService.cancel(orderId);
        }
    }
}

Bu soddalashtirilgan. Production’da retry, timeout, state machine, event log, idempotency kerak bo‘ladi.


Orchestration afzalliklari

business flow bitta joyda ko‘rinadi
debug qilish osonroq
compensation tartibli
murakkab processlar uchun yaxshi
monitoring qilish oson

Orchestration kamchiliklari

orchestrator ko‘p narsani biladi
coupling kuchayishi mumkin
orchestrator failure nuqtasi bo‘lishi mumkin
service’lar orasida command-style dependency paydo bo‘ladi

9. Choreography vs Orchestration

Mezon

Choreography

Orchestration

Boshqaruvchi

Yo‘q

Bor

Coupling

Pastroq

Yuqoriroq

Flow visibility

Pastroq

Yuqori

Debug

Qiyinroq

Osonroq

Kichik flow

Yaxshi

Ortiqcha bo‘lishi mumkin

Murakkab flow

Chalkashishi mumkin

Yaxshi

Monitoring

Tarqoq

Markazlashgan

Qisqa qoida:

Kichik, oddiy event flow → choreography
Murakkab, ko‘p qadamli biznes process → orchestration

10. Transactional Outbox Pattern

Distributed system’da eng katta muammolardan biri:

Database’ga yozildi, lekin event publish bo‘lmadi.

Masalan:

@Transactional
public void createOrder(CreateOrderCommand command) {
    orderRepository.save(order);

    kafkaTemplate.send("order-created", event);
}

Bu xavfli.

Nima bo‘lishi mumkin?

Order DB’ga yozildi
Kafka publish vaqtida broker down bo‘ldi
Transaction commit bo‘ldi
Lekin event ketmadi
Payment service order borligini bilmadi

Yoki teskarisi:

Kafka event ketdi
DB transaction rollback bo‘ldi
Payment service mavjud bo‘lmagan order uchun payment boshladi

11. Outbox yechimi

Transactional Outbox’da biznes data va event bir xil database transaction’da yoziladi.

orders table
outbox_events table

Transaction:

1. orders table’ga order yoziladi
2. outbox_events table’ga OrderCreated event yoziladi
3. transaction commit

Keyin alohida process outbox’dan eventni brokerga yuboradi.


Outbox table

CREATE TABLE outbox_events (
    id UUID PRIMARY KEY,
    aggregate_type VARCHAR(100) NOT NULL,
    aggregate_id VARCHAR(100) NOT NULL,
    event_type VARCHAR(100) NOT NULL,
    payload JSONB NOT NULL,
    status VARCHAR(30) NOT NULL,
    created_at TIMESTAMP NOT NULL,
    published_at TIMESTAMP
);

Order create

@Transactional
public void createOrder(CreateOrderCommand command) {
    Order order = Order.create(command.customerId(), command.items());

    orderRepository.save(order);

    OutboxEvent event = OutboxEvent.of(
            "Order",
            order.getId().toString(),
            "OrderCreated",
            toJson(new OrderCreatedEvent(order.getId(), order.getTotal()))
    );

    outboxRepository.save(event);
}

Muhim:

Order va OutboxEvent bitta transaction’da commit bo‘ladi.

12. Outbox publisher

Keyin background worker eventlarni publish qiladi:

@Scheduled(fixedDelay = 1000)
public void publishOutboxEvents() {
    List<OutboxEvent> events = outboxRepository.findTop100ByStatus("NEW");

    for (OutboxEvent event : events) {
        kafkaTemplate.send(event.getEventType(), event.getPayload());

        event.markPublished();
        outboxRepository.save(event);
    }
}

Bu oddiy variant. Production’da quyidagilar kerak:

batch processing
locking
retry count
dead-letter status
idempotent publish
ordering
metrics
backpressure

13. Outbox + Debezium CDC

Outbox polling qilish mumkin, lekin katta system’da ko‘pincha CDC ishlatiladi.

CDC - Change Data Capture.

Flow:

Application
   ↓
orders + outbox_events DB’ga yozadi
   ↓
Debezium database transaction log’ni o‘qiydi
   ↓
Outbox row paydo bo‘lganini ko‘radi
   ↓
Kafka’ga event chiqaradi

Architecture:

order-service
   ↓ local transaction
PostgreSQL
   ↓ WAL/binlog
Debezium
   ↓
Kafka topic
   ↓
payment-service

Nima uchun Debezium yaxshi?

application polling qilmaydi
DB transaction log’dan ishonchli o‘qiydi
event yo‘qolish xavfi kamayadi
high-throughput event publishing uchun yaxshi
outbox relay alohida infrastructure bo‘ladi

Lekin complexity oshadi:

Debezium connector setup
Kafka dependency
schema evolution
connector monitoring
offset management
DLQ strategy

14. Outbox pattern nimani kafolatlaydi?

Transactional Outbox shuni kafolatlaydi:

Agar order DB’da bo‘lsa, outbox event ham DB’da bo‘ladi.

Lekin shuni kafolatlamaydi:

consumer eventni faqat bir marta oladi
event duplicate bo‘lmaydi
event doim tartibda keladi
consumer xatosiz ishlaydi

Shuning uchun keyingi pattern kerak:

Idempotent Consumer

15. Idempotent Consumer Pattern

Event-driven system’da bitta event bir necha marta kelishi mumkin.

Sabablar:

producer retry
broker retry
consumer ack bermadi
consumer qayta ishga tushdi
network timeout
outbox relay duplicate publish qildi

Demak consumer shunday yozilishi kerak:

Bitta event 2 marta kelsa ham biznes natija 1 marta bajarilsin.

Bu idempotency deb ataladi.


Yomon consumerga misol:

@KafkaListener(topics = "payment-completed")
public void on(PaymentCompletedEvent event) {
    orderService.markPaid(event.orderId());
    notificationService.sendPaymentSuccess(event.orderId());
}

Agar event 2 marta kelsa:

order ikki marta update bo‘lishi mumkin
notification ikki marta ketishi mumkin
bonus ikki marta yozilishi mumkin

Yaxshi consumer: processed_events table

CREATE TABLE processed_events (
    event_id UUID PRIMARY KEY,
    processed_at TIMESTAMP NOT NULL
);

Consumer:

@Transactional
public void handle(PaymentCompletedEvent event) {
    if (processedEventRepository.existsById(event.eventId())) {
        return;
    }

    orderService.markPaid(event.orderId());

    processedEventRepository.save(new ProcessedEvent(
            event.eventId(),
            Instant.now()
    ));
}

Bu bilan event duplicate kelsa, ikkinchi marta bajarilmaydi.


16. Idempotency key

REST API’da ham idempotency kerak bo‘ladi.

Masalan payment API:

POST /payments
Idempotency-Key: 8f1a-xyz-123

Agar client timeout sabab requestni qayta yuborsa, payment ikki marta olinmasligi kerak.

Table:

CREATE TABLE idempotency_keys (
    key VARCHAR(100) PRIMARY KEY,
    request_hash VARCHAR(255),
    response_body JSONB,
    status VARCHAR(30),
    created_at TIMESTAMP
);

Flow:

1. Request keldi
2. Idempotency-Key tekshirildi
3. Oldin bajarilgan bo‘lsa, eski response qaytarildi
4. Yangi bo‘lsa, operation bajarildi
5. Natija key bilan saqlandi

17. Idempotent Consumer’da muhim qoidalar

event’da unique eventId bo‘lsin
processed_events table transaction ichida yozilsin
business operation va processed marker bitta transaction’da bo‘lsin
side effectlar ehtiyot bilan qilinsin
notification/email ham duplicate-safe bo‘lsin

Yomon:

email yuborildi
keyin processed_events yozishda xato bo‘ldi
event qayta keldi
email yana yuborildi

Yechim:

email ham outbox orqali yuboriladi
yoki notification service idempotent bo‘ladi

18. Distributed Locking

Distributed lock - bir nechta instance bir xil ishni bir vaqtda bajarmasligi uchun lock.

Masalan:

order-service 3 ta podda ishlayapti
har pod scheduled job ishga tushiradi
invoice generation faqat bitta podda ishlashi kerak

Distributed lock kerak bo‘lishi mumkin:

scheduled job faqat bitta instance’da
bir resource’ni bir vaqtda bitta process update qilsin
inventory reservation
leader election
rate-limited external API call

19. Redis/Redisson lock

Spring projectlarda ko‘p ishlatiladigan variant:

RLock lock = redissonClient.getLock("invoice-generation");

boolean acquired = lock.tryLock(5, 30, TimeUnit.SECONDS);

if (!acquired) {
    return;
}

try {
    invoiceService.generateInvoices();
} finally {
    lock.unlock();
}

Bu nimani anglatadi?

5 sekund ichida lock olishga urinadi
lock olinsa 30 sekund lease time
ish tugasa unlock qiladi

20. Distributed lock xavflari

Distributed lock oson ko‘rinadi, lekin xavfli.

Muammolar:

lock olindi, process o‘ldi
lease time noto‘g‘ri tanlandi
network partition
clock drift
long-running job lease’dan uzoq davom etdi
unlock noto‘g‘ri instance’dan qilindi
Redis unavailable bo‘ldi

Qoida:

Distributed lock’ni transaction o‘rniga ishlatmang. U faqat coordination uchun.


21. Database lock alternativasi

Ba’zan DB lock yetarli bo‘ladi.

Masalan PostgreSQL advisory lock:

SELECT pg_try_advisory_lock(12345);

Yoki row-level lock:

SELECT *
FROM jobs
WHERE status = 'NEW'
FOR UPDATE SKIP LOCKED
LIMIT 100;

SKIP LOCKED job processing uchun juda foydali:

bir nechta worker bor
har biri lock bo‘lmagan joblarni oladi
bir job ikki workerga tushmaydi

22. Distributed lock qachon kerak emas?

Ko‘p holatda lock o‘rniga yaxshiroq pattern bor:

Muammo

Lock o‘rniga

Duplicate event

Idempotent consumer

Event publish reliability

Outbox

Concurrent update

Optimistic locking

Job processing

Queue + SKIP LOCKED

Global order

Kafka partition key

Payment duplicate

Idempotency key

Arxitektor qoida:

Lock - oxirgi variantlardan biri. Avval idempotency, queue, database constraint, optimistic locking o‘ylansin.


23. Two-Phase Commit - 2PC

Two-Phase Commit - bir nechta resource orasida distributed transaction qilish usuli.

Masalan:

order_db
payment_db
inventory_db

hammasi bitta global transaction’da commit/rollback bo‘lishi kerak.

2PC ikki bosqich:

1. Prepare phase
2. Commit phase

Coordinator resource’lardan so‘raydi:

"Commit qilishga tayyormisiz?"

Hammasi "ha" desa:

commit

Biri "yo‘q" desa:

rollback

24. 2PC nega yomon?

Nazariy jihatdan chiroyli. Amalda distributed microservice’da ko‘pincha yomon.

Kamchiliklar:

coordinator kerak
resource’lar lock ushlab turadi
latency oshadi
availability pasayadi
network failure’da murakkab holat
service autonomy buziladi
cloud-native architecture’ga mos emas
scaling qiyin

Microservice’da bitta service yiqilsa, butun transaction osilib qolishi mumkin.


25. 2PC qachon ishlatilishi mumkin?

Ba’zi enterprise systemlarda hali ham ishlatiladi:

legacy enterprise app
XA transaction support bor
kam traffic
strong consistency juda muhim
bitta organization ichidagi controlled environment

Lekin zamonaviy cloud-native Spring microservice architecture’da ko‘pincha:

SAGA + Outbox + Idempotency

yaxshiroq.


26. 2PC o‘rniga nima?

Kerak bo‘lgan narsa

Tavsiya

Cross-service business transaction

SAGA

Reliable event publish

Transactional Outbox

DB change event

Debezium CDC

Duplicate eventdan himoya

Idempotent Consumer

Concurrent update

Optimistic Locking

One-at-a-time job

Queue / DB lock / Redis lock

Strong audit

Event log / outbox / audit table


27. Consistency turlari

Distributed system’da ko‘pincha eventual consistency qabul qilinadi.

Strong consistency

hamma joy darhol bir xil

Monolith + bitta DB’da osonroq.

Eventual consistency

hozircha order CREATED
bir necha sekunddan keyin PAID
keyin CONFIRMED

Ya’ni system vaqt o‘tib consistent bo‘ladi.

Misol:

Order created
Payment processing
Payment completed
Order confirmed

Foydalanuvchiga status ko‘rsatiladi:

{
  "orderId": 123,
  "status": "PAYMENT_PROCESSING"
}

28. Eventual consistency UX masalasi

Backend eventual consistent bo‘lsa, frontend ham shuni tushunishi kerak.

Yomon UX:

Buyurtma yaratildi, lekin payment hali tugamagan.
Frontend "xato" deb ko‘rsatadi.

Yaxshi UX:

Buyurtma qabul qilindi.
To‘lov tekshirilmoqda.
Statusni yangilab turamiz.

Statuslar:

CREATED
STOCK_RESERVED
PAYMENT_PROCESSING
PAID
CONFIRMED
FAILED
CANCELLED

29. Ordering muammosi

Eventlar noto‘g‘ri tartibda kelishi mumkin:

PaymentCompletedEvent oldin keldi
OrderCreatedEvent keyin keldi

Yoki bir aggregate uchun eventlar tartibi buziladi.

Yechimlar:

Kafka partition key = aggregateId
event version
sequence number
consumer buffering
idempotent state transition

Masalan:

public record OrderEvent(
        UUID eventId,
        Long orderId,
        long version,
        String type,
        Instant occurredAt
) {}

Consumer eski versionni ko‘rsa ignore qiladi.


30. Optimistic locking

Concurrent update uchun distributed lock shart emas. Ko‘p holatda optimistic locking yetarli.

Entity:

@Entity
public class OrderEntity {

    @Id
    private Long id;

    @Version
    private Long version;

    private OrderStatus status;
}

Agar ikki transaction bir orderni update qilsa:

birinchisi yutadi
ikkinchisi OptimisticLockException oladi

Keyin retry yoki business error.

Bu inventory, order status, account update kabi joylarda foydali.


31. Transactional Inbox Pattern

Outbox producer tomonida reliable event publish uchun.

Inbox consumer tomonida reliable event processing uchun.

incoming_events table

Consumer eventni avval inbox’ga yozadi, keyin process qiladi.

Flow:

Kafka event keldi
   ↓
incoming_events table’ga yozildi
   ↓
business processing
   ↓
processed status

Bu ayniqsa complex consumer processing uchun foydali bo'ladi.


32. Dead Letter Queue - DLQ

Agar event qayta-qayta process bo‘lmasa, cheksiz retry qilish yomon.

Yechim:

retry 3 marta
keyin DLQ topic
alert
manual investigation
replay tool

Flow:

payment-events
   ↓
consumer fail
   ↓ retry
consumer fail
   ↓ retry
consumer fail
   ↓
payment-events-dlq

DLQ production’da shart:

xato event yo‘qolmasin
consumer to‘xtab qolmasin
manual fix/replay bo‘lsin

33. Real flow: Order checkout

Production-ready distributed flow:

1. order-service order yaratadi
2. order_db orders + outbox_events yoziladi
3. Debezium outbox eventni Kafka’ga chiqaradi
4. inventory-service OrderCreatedEvent eshitadi
5. inventory stock reserve qiladi
6. inventory outbox StockReservedEvent chiqaradi
7. payment-service StockReservedEvent eshitadi
8. payment idempotency key bilan charge qiladi
9. PaymentCompletedEvent chiqadi
10. order-service eventni idempotent consume qiladi
11. order status CONFIRMED bo‘ladi

Failure case:

payment fail
   ↓
PaymentFailedEvent
   ↓
inventory stock release
   ↓
order status CANCELLED

34. Spring Boot structure

com.company.order
 ├── domain
 │    ├── Order.java
 │    └── OrderStatus.java
 │
 ├── application
 │    ├── CreateOrderHandler.java
 │    ├── ConfirmOrderHandler.java
 │    └── CancelOrderHandler.java
 │
 ├── outbox
 │    ├── OutboxEvent.java
 │    ├── OutboxRepository.java
 │    └── OutboxService.java
 │
 ├── inbox
 │    ├── ProcessedEvent.java
 │    └── ProcessedEventRepository.java
 │
 ├── messaging
 │    ├── OrderEventPublisher.java
 │    └── PaymentCompletedListener.java
 │
 └── web
      └── OrderController.java

35. Eng ko‘p xatolar

Xato 1: @Transactional bilan Kafka publish qilish

@Transactional
public void createOrder() {
    orderRepository.save(order);
    kafkaTemplate.send("order-created", event);
}

Bu atomic emas.

Yaxshiroq:

DB + Outbox bitta transaction
Kafka publish alohida relay/CDC orqali

Xato 2: Consumer idempotent emas

Duplicate event kelganda biznes ikki marta bajariladi.


Xato 3: SAGA’da compensation yo‘q

Flow fail bo‘lsa system yarim holatda qoladi.


Xato 4: Distributed lock bilan hamma narsani yechish

Lock consistency muammolarini to‘liq hal qilmaydi. Ko‘p holatda idempotency va outbox kerak.


Xato 5: 2PC’ni microservice’da default tanlash

Strong consistency xohishi availability va scalability’ni yomonlashtirishi mumkin.


Xato 6: Event schema versioning yo‘q

Event o‘zgarsa consumerlar buziladi.

Yaxshi event:

{
  "eventId": "uuid",
  "eventType": "OrderCreated",
  "eventVersion": 1,
  "occurredAt": "2026-05-21T10:00:00Z",
  "payload": {
    "orderId": 123
  }
}

36. Architect checklist

Distributed data design qilishdan oldin savollar javob berish kerak:

Har service o‘z database’iga egami?
Cross-service transaction bormi?
Failure bo‘lsa compensation qanday?
Event publish reliable bo‘ladimi?
Consumer duplicate eventga tayyormi?
Event ordering kerakmi?
DLQ strategy bormi?
Retry policy qanday?
Business statuslar eventual consistency’ni ko‘rsatadimi?
Observability event flow’ni ko‘rsatadimi?
2PC haqiqatan kerakmi yoki SAGA yetadimi?

37. Qisqa tavsiya

Katta Spring microservice system uchun odatiy stack:

SAGA
+ Transactional Outbox
+ Debezium CDC
+ Kafka
+ Idempotent Consumer
+ DLQ
+ Optimistic Locking
+ Observability

Lock kerak bo‘lsa:

avval database constraint / optimistic lock / queue o‘yla
keyin Redis/Redisson distributed lock

2PC kerak bo‘lsa:

juda ehtiyot bo‘l
cloud-native microservice’da default tanlama

38. Arxitektor xulosasi

Distributed data patterns - distributed system’da "hammasi bitta transaction bo‘lsin" degan fikrdan voz kechib, real failure’larni boshqarish yondashuvi hisoblanadi.

Asosiy formula:

Local transaction
+ Reliable event publishing
+ Idempotent consuming
+ Compensation
+ Retry/DLQ
+ Observability
= production-ready distributed data architecture

Eng muhim qoida:

Distributed system’da failure normal holat. Architecture failure bo‘lmasligiga emas, failure bo‘lganda system to‘g‘ri tiklanishiga quriladi.