← 返回首页

分布式事务:跨服务的数据一致性

📂 java ⏱ 2 min 229 words

分布式事务:跨服务的数据一致性

概述

在微服务架构中,一个业务操作可能涉及多个服务的数据变更。分布式事务保证这些操作要么全部成功,要么全部失败。

1. CAP与BASE理论

// CAP定理:一致性(C)、可用性(A)、分区容错(P),三者只能满足两个
// BASE理论:基本可用(BA)、软状态(S)、最终一致性(E)

2. TCC模式

public interface TccService {
    boolean try_(Map<String, Object> params);
    boolean confirm(Map<String, Object> params);
    boolean cancel(Map<String, Object> params);
}

@Service
public class InventoryTccService implements TccService {
    @Override
    public boolean try_(Map<String, Object> params) {
        Long productId = (Long) params.get("productId");
        int quantity = (int) params.get("quantity");
        return inventoryRepository.freeze(productId, quantity);
    }

    @Override
    public boolean confirm(Map<String, Object> params) {
        Long productId = (Long) params.get("productId");
        int quantity = (int) params.get("quantity");
        return inventoryRepository.confirmDeduct(productId, quantity);
    }

    @Override
    public boolean cancel(Map<String, Object> params) {
        Long productId = (Long) params.get("productId");
        int quantity = (int) params.get("quantity");
        return inventoryRepository.release(productId, quantity);
    }
}

3. Saga模式

@Service
public class OrderSaga {
    @SagaStep(compensation = "cancelOrder")
    public void createOrder(Order order) {
        orderRepository.save(order);
    }

    @SagaStep(compensation = "releaseInventory")
    public void deductInventory(Order order) {
        inventoryService.deduct(order.getProductId(), order.getQuantity());
    }

    public void cancelOrder(Order order) {
        orderRepository.delete(order.getId());
    }
}

4. Seata框架

import io.seata.spring.annotation.GlobalTransactional;

@Service
public class OrderService {
    @GlobalTransactional
    public void createOrder(Order order) {
        orderRepository.save(order);
        inventoryClient.deduct(order.getProductId(), order.getQuantity());
        paymentClient.charge(order.getUserId(), order.getAmount());
    }
}

5. 本地消息表

@Service
public class OrderServiceWithMessageTable {
    @Transactional
    public void createOrder(Order order) {
        orderRepository.save(order);
        Message message = new Message("ORDER_CREATED", JSON.toJSONString(order));
        messageRepository.save(message);
    }

    @Scheduled(fixedDelay = 5000)
    public void retryMessages() {
        List<Message> messages = messageRepository.findUnsent();
        for (Message message : messages) {
            try {
                rabbitTemplate.convertAndSend("order.exchange", "order.created", message.getContent());
                message.setSent(true);
                messageRepository.save(message);
            } catch (Exception e) {}
        }
    }
}

最佳实践

  1. 优先最终一致性:避免强一致性分布式事务
  2. 使用Seata:简化分布式事务管理
  3. TCC模式:适合对一致性要求高的场景
  4. Saga模式:适合长事务场景
  5. 本地消息表:实现可靠的最终一致性

总结

分布式事务是微服务架构中的重要挑战,掌握TCC、Saga、Seata等解决方案,可以有效地保证跨服务的数据一致性。