分布式事务是个很大的话题,三言两语恐怕说不清。你说的这些中间件还有框架都没提供现成的分布式事务解决方案,dubbo本身虽然是个分布式服务框架,但他没提供解决分布式事务的功能,其他比如zk和redis有提供分布式锁,但这跟提供分布式事务解决方案是两码事。
分布式事务是在应用服务化后首先碰到的一个问题(其他比如服务治理这个先不谈),实际上可能都不用服务化,你随便来个分库就会遇到事务的不一致问题。目前解决的办法有基于XA的2pc两阶段提交,实际上就是整个事务过程由事务管理器和资源管理器来共同参与。这么一说可能题主就明白了这是位于资源层面的解决方案,说白了就是你的数据库或者MQ要支持两阶段提交协议,由于在整个事务过程中会一直锁定资源,而且涉及到网络操作,那这个东西就不太可靠,而且会影响性能,扩展性和可用性都不友好,同时对于服务层面的分布式它是搞定不定的。所以后面又搞出来个tcc,这个类似2pc,只是它是位于业务层面,基本的思路是把比较长的分布式事务拆分成本地的短事务。这需要结合业务的特点去设计,比如买10块钱的东西,针对支付这个服务,在进行扣费的时候先有个冻结用户10块钱的动作,这个就是try。等到后面tcc框架发起confirm操作时才真正把10块钱扣掉,如果tcc框架发起cancel操作则把10块钱解冻。需要注意的是由于confirm和cancel可能失败,因此可以结合全局事务ID设计成幂等性的接口。
上面两种从某种程度上来讲都能提供比较强的一致性,但是有很多场景是不需要这种强一致性的。根据CAP(一致性、可用性、可靠性)的理论,鱼和熊掌不可兼得,可靠性是必须要的,所以需要在C和A之间做平衡,实际上在互联网领域A也是必须的,因此就不得不在C上做文章。于是有了弱一致或者最终一致,它不要求你在做完一个操作后能立马看到效果,只要在可接受的时间内看到正确的结果即可。这方面的内容epay的架构师有过介绍,目前业界用这种的比较多,Sina Visitor System 这篇文章讲解的比较详细。其解决分布式事务的思路就是避免分布式事务,具体来说就是利用本地事务+异步消息+重试+幂等去保证整个系统数据的最终一致性。