本地事务
概念
事务也就是ACID
- 原子性
- 一致性
- 隔离性
- 持久性
我们拿A给B转账为例,在这个过程中原子性是指A钱少了,B钱多了,这件事要么都成功要么都失败;一致性是指A钱少
B钱多了这件事情要一致;隔离性是说转账这件事情不能受到别的事务所影响;持久性是指转账成功后钱要保证到账
本地事务存在的问题
因为服务自治本地事务只能回滚自己的事务。
场景:当订单服务调用库存服务进行锁定库存的时候,如果锁库存的时候抛出了异常那么订单服务还是可以感知到,但如果库存服务锁定库存成功,但是因为网络的因素导致了调用库存服务失败了,这时候订单服务还是会抛出异常,那么订单服务进行了事务回滚但是库存已经锁了。又比如:订单服务调用库存服务成功,之后再调用用户服务保存用户积分信息,如果用户服务抛出了异常这时候虽然订单服务感知到了进行了事务回滚但是库存服务是不能做到事务回滚的,因为微服务自治。
CAP原则
C:一致性,在分布式系统中进行所有数据备份,在同一时刻是否是同样的值
A:可用性,在集群中一部分节点故障后,集群整体是否还能响应客户端的请求
P:分区容错性,不同区域的节点相互访问的时候可能会出现调用失败的情况
CAP原则是指,这三个要素最多只能实现两点,不可能三者兼顾,所以一个分布式系统要么是CP系统要么是AP系统
分布式系统中实现一致性的raft算法
CAP原则的延申概念BASE
- 基本可用
- 响应时间上的损失
- 功能上的损失,将一部分用户引导到降级页面
- 软状态,中间的一种状态
- 最终一致性,系统中所有数据副本经过一段时间后最终一致
分布式事务的几种解决方案
2PC模式
将提交数据分成两个阶段,因此也叫二阶提交协议
柔性事务-TCC事务补偿性方案
刚性事务:遵循ACID原则,强一致性
柔性事务:遵循BASE原则,最终一致性
柔性事务-最大努力通知型方案
不停的确认是否执行成功,例如支付宝的支付案例
柔性事务-可靠消息+最终一致性方案(异步确保型)
可靠消息是指要保证mq中消息不丢失,比如:在发送消息的时候要保证消息不丢失,可以开启手动确认机制
@Service @RabbitListener(queues = "order.release.order.queue") public class OrderCloseListener { @Autowired OrderService orderService; @RabbitHandler public void orderClose(OrderEntity orderEntity, Channel channel, Message message) throws IOException { try { orderService.orderClose(orderEntity); channel.basicAck(message.getMessageProperties().getDeliveryTag(),false); }catch (Exception e){ channel.basicReject(message.getMessageProperties().getDeliveryTag(),true); } } }