分布式事务:跨服务的数据一致性
分布式事务:跨服务的数据一致性
概述
在微服务架构中,一个业务操作可能涉及多个服务的数据变更。分布式事务保证这些操作要么全部成功,要么全部失败。
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) {}
}
}
}
最佳实践
- 优先最终一致性:避免强一致性分布式事务
- 使用Seata:简化分布式事务管理
- TCC模式:适合对一致性要求高的场景
- Saga模式:适合长事务场景
- 本地消息表:实现可靠的最终一致性
总结
分布式事务是微服务架构中的重要挑战,掌握TCC、Saga、Seata等解决方案,可以有效地保证跨服务的数据一致性。