看标题就知道,这个又是个在面试中被问到的问题。这个问题其实是在我上次换工作的时候面试被问到过几次,之前也没在意过,觉得这个东西可能比较深奥,我直接说不理解吧。但是随着Java开发这个行业越来越卷,这次换工作一定要做好充足的准备。把之前落下的坑都填好,再出去受虐(面试)。
什么是分布式事务我们都知道本地事务是有四个特性的:原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)。
本地事务的ACID一般都是靠关系型数据库来完成的,非关系型数据库一般也可以考数据库来实现,redis这种不能回滚的弱事务除外。
但是在分布式系统中一次操作由多个服务协同完成,这种一次事务操作涉及多个系统通过网络协同完成的过程称为分布式事务。
多个服务之间的可以是同一个数据库,也可以是多个数据库。
另外如果是在同一个服务中,使用了多个数据源连接了不同的数据库,当一个事务需要操作多个数据源的时候也是属于分布式事务。
CAP理论是目前分布式系统中的处理分布式事务的理论基础。主要是在目前分布式系统中都无法同时满足如下三个属性:
一致性(Consistency):多个服务的数据需要保持在同一时刻的数据一致性。
可用性(Availability):指单个系统提供的服务需要一直保持可用状态,对于每一个请求,都能及时的响应,超时或不无响应则认为系统不可用。
分区容错性(Partition Tolerance):分布式系统再遇到任何网络分区故障时,仍能够保证对外提供满足一致性和可用性的服务,除非整个网络环境发生故障。
在分布式系统中。一个服务最多只能保证上面其中任何两个属性,并不能同时满足。
在保证分区容错性的时候并不能保证数据的一致性和服务的可用性。如果要提高服务的可用性,就要增加多个结点,虽然节点越多可用性越好,但是数据一致性就会越差。
这样在分布式系统设计中,同时满足“一致性”、“可用性”和“分区容错性”几乎是不可能的。
CAP应用组合【CA】放弃分区容错性:放弃分区容错性,也要保证网络可用,最简单的做法就是将所有数据都放在同一个节点上,虽然这样无法保证100%系统不出错,但至少不会出现由于网络分区带来的负面影响。
【CP】放弃可用性:放弃可用性,是指一但遇到网络分区或其他系统问题时,那受到影响的服务需要等待一定时间,应用等待期间系统无法对外提供正常服务。即短时间内不可用。
【AP】放弃一致性:所谓的放弃一致性,其实并不是完全的不需要一致性,而是放弃强一致性,保证了数据最终一致性。
BASE理论在分布式系统中,往往追求的是可比性,一般重要程度比一致性高。所以就又出现了另一个理论,就是BASE理论,是对CAP理论的一个扩充。
Base Availability(基本可用);
Soft state(软状态);
Eventually consistent(最终一致性);
BASE理论是对CAP理论中的一致性和可用性的一种权衡的结果,主要思想就是:无法做到强一致,但每个应用可以根据自身业务的特点,采用适当的方式来使系统达到最终的一致性。
分布式事务的解决方案分布式事务的解决方案,目前市面上是有几类的方式的。
2PC(两阶段提交)、3PC(三阶段提交);
TCC方案;
本地消息表;
可靠消息最终一致性方案;
最大努力通知方案;
2PC(两阶段提交)两阶段提交主要是将提交事务和执行事务分为了两步。
第一阶段:事务协调器通知参与者准备提交事务,参与者准备成功之后向协调者返回成功,若有一个参与者返回的是准备不成功,那么事务执行失败。
第二阶段:事务协调器根据各个参与者的第一阶段的返回结果,发起最终提交事务的请求,若有一个参与者提交失败,则所有参与者都执行回滚,事务执行失败。
这种属于强一致性的实现,因为在多个服务间的事务执行过程中,有可能第一个服务的事务已经提交了,第二服务提交失败了,虽然说可以让第二个服务的事务回滚但是第一个服务有可能事务已经执行完成了,无法进行回滚了。所以多数情况下是将第二个服务其实是进行重试提交,然后直到重试成功为止,重试到一定次数后仍没有成功就需要预警出来人工干预了。