在讲分布式事务的实现方案之前,我们要先了解到分布式事务的由来,以及一部分相关的原理,才能更深入的了解到为什么分布式事务会产生一些问题。
要注意的是,我们说的分布式事务,是分布式服务里面的事务处理机制,而不是多个数据源带来的分布式事务。
为什么会有分布式事务一致性问题?
在分布式环境下,为什么会有分布式事务一致性问题?而且为什么这个问题,是一个必然出现的一个问题?
要追究缘由,那么就必须从分布式服务这个概念中寻找。
在分布式领域,有一个很著名的理论,CAP定理,这个定理描述了在分布式系统中,涉及到共享数据问题的时候,以下三种特性只能满足其中两种。(不要问为什么CAP理论为什么成立,这个CAP理论已经被证实了!)
- 一致性:代表数据在任何时候,任何节点中看到都是要符合预期的。
- 可用性:代表系统不间断的提供服务的能力。
- 分区容忍性:代表在分布式环境中,因为网络原因彼此失联后,系统依然可以正确的提供服务。
那么为什么在后来的分布式设计中,所有的设计框架都抛弃了一致性,选择了可用性和分区容忍性,导致了分布式事务问题的出现呢?
首先是 分区容忍性,如果不想要分区容忍性,那就要保证分区之间的网络通信是100%不会出现问题,但是那是不可能的,网络通信问题是客观存在的,没有办法避免。
如果不想要 可用性,那也就是说在分布式环境中,其中一个节点出现问题了,所有的节点都要停止提供服务。在这种情况下,分布式还算是分布式吗?
所以,最后只能舍弃了 一致性,这就是为什么在分布式环境中会有分布式事务一致性问题的原因!
为什么分布式事务是个大问题?
在思考这个问题的时候,我们必须把自己代入到一个实际的应用场景中,这样才能得到一个更为真实贴切的结果。
在微服务的实际开发过程中,一个简单的操作,可能涉及到多个服务,那么如何保证这个操作涉及到每一个服务都成功,或者都失败呢?或者说,如何保证每个服务最终实现后的结果,会如我们所想呢?
假设一个操作T1,涉及到A服务,B服务,C服务,这三个服务都有自己独立的数据库。
那么在实际的应用场景中,我们应该保证如下几点:
- A服务,B服务,C服务如果有一个执行失败了,那么其他服务应该撤销其操作。
- 如果其中一个服务执行失败了,已经执行的服务操作无法撤销,那么必须通过其他机制保障其最终结果是撤销了的。
- 如果一个服务执行失败了,已经执行的操作无法撤销,但是这个操作会有重试机制,那么必须保证已经执行的操作,再次执行的时候,要保证其幂等性。
从以上三点可以看出几个技术实现的难点:
- 如何保证一个服务执行失败,其他服务可以撤销的操作?
- 一个服务执行失败了,其他服务无法撤销,要通过什么样的手段提供其最终一致性?
- 一个服务,如何保证其多次执行相同操作的时候是幂等的?
在实际的代码开发过程中,这些问题,在不同的业务场景中,都有着不同的解决方案,因地制宜的选择,因为没有一个放之四海而皆准的道理的。
总结
分布式事务一致性问题,是一个客观存在,且在实际开发过程中,不得不面对的一个问题,那么我们在面对不同的环境下,如何进行取舍,这考验到了我们的技术选型能力,以及团队的技术实力。
这么多的技术难点,而且在不同的业务场景下,不同的团队构成中,还需要做各种各样的取舍,这就是为什么我们遇到分布式事务问题的时候,如此为难的原因所在。