在说分布式事务之前,我们先从数据库事务说起。数据库事务可能大家都很熟悉,在开发过程中也会经常使用到。但是即使如此,可能对于一些细节问题,很多人仍然不清楚。比如很多人都知道数据库事务的几个特性:原子性(Atomicity )、一致性( Consistency )、隔离性或独立性( Isolation)和持久性(Durabilily),简称就是ACID。但是再往下比如问到隔离性指的是什么的时候可能就不知道了,或者是知道隔离性是什么但是再问到数据库实现隔离的都有哪些级别,或者是每个级别他们有什么区别的时候可能就不知道了。本文并不打算介绍这些数据库事务的这些东西,有兴趣可以搜索一下相关资料。不过有一个知识点我们需要了解,就是假如数据库在提交事务的时候突然断电,那么它是怎么样恢复的呢?为什么要提到这个知识点呢?因为分布式系统的核心就是处理各种异常情况,这也是分布式系统复杂的地方,因为分布式的网络环境很复杂,这种“断电”故障要比单机多很多,所以我们在做分布式系统的时候,最先考虑的就是这种情况。这些异常可能有 机器宕机、网络异常、消息丢失、消息乱序、数据错误、不可靠的TCP、存储数据丢失、其他异常等等...我们接着说本地事务数据库断电的这种情况,它是怎么保证数据一致性的呢?我们使用SQL Server来举例,我们知道我们在使用 SQL Server 数据库是由两个文件组成的,一个数据库文件和一个日志文件,通常情况下,日志文件都要比数据库文件大很多。数据库进行任何写入操作的时候都是要先写日志的,同样的道理,我们在执行事务的时候数据库首先会记录下这个事务的redo操作日志,然后才开始真正操作数据库,在操作之前首先会把日志文件写入磁盘,那么当突然断电的时候,即使操作没有完成,在重新启动数据库时候,数据库会根据当前数据的情况进行undo回滚或者是redo前滚,这样就保证了数据的强一致性。接着,我们就说一下分布式事务。
分布式理论
当我们的单个数据库的性能产生瓶颈的时候,我们可能会对数据库进行分区,这里所说的分区指的是物理分区,分区之后可能不同的库就处于不同的服务器上了,这个时候单个数据库的ACID已经不能适应这种情况了,而在这种ACID的集群环境下,再想保证集群的ACID几乎是很难达到,或者即使能达到那么效率和性能会大幅下降,最为关键的是再很难扩展新的分区了,这个时候如果再追求集群的ACID会导致我们的系统变得很差,这时我们就需要引入一个新的理论原则来适应这种集群的情况,就是 CAP 原则或者叫CAP定理,那么CAP定理指的是什么呢?
具体地讲在分布式系统中,在任何数据库设计中,一个Web应用至多只能同时支持上面的两个属性。显然,任何横向扩展策略都要依赖于数据分区。因此,设计人员必须在一致性与可用性之间做出选择。这个定理在迄今为止的分布式系统中都是适用的! 为什么这么说呢?这个时候有同学可能会把数据库的2PC(两阶段提交)搬出来说话了。OK,我们就来看一下数据库的两阶段提交。对数据库分布式事务有了解的同学一定知道数据库支持的2PC,又叫做 XA Transactions。
MySQL从5.5版本开始支持,SQL Server 2005 开始支持,Oracle 7 开始支持。
上面介绍的那些分布式事务的处理方案你在其他地方或许也可以看到,但是并没有相关的实际代码或者是开源代码,所以算不上什么干货,下面就放干货了。在 .NET 领域,似乎没有什么现成的关于分布式事务的解决方案,或者说是有但未开源。据笔者了解,有一些公司内部其实是有这种解决方案的,但是也是作为公司的一个核心产品之一,并未开源...鉴于以上原因,所以博主就打算自己写一个并且开源出来,所以从17年初就开始做这个事情,然后花了大半年的时间在一直不断完善,就是下面这个 CAP。Github CAP:这里的 CAP 就不是 CAP 理论了,而是一个 .NET 分布式事务解决方案的名字。详细介绍:http://www.cnblogs.com/savorboard/p/cap.html相关文档:http://www.cnblogs.com/savorboard/p/cap-document.html夸张的是,这个解决方案是具有可视化界面(Dashboard)的,你可以很方面的看到哪些消息执行成功,哪些消息执行失败,到底是发送失败还是处理失败,一眼便知。最夸张的是,这个解决方案的可视化界面还提供了实时动态图表,这样不但可以看到实时的消息发送及处理情况,连当前的系统处理消息的速度都可以看到,还可以看到过去24小时内的历史消息吞吐量。最最夸张的是,这个解决方案的还帮你集成了 Consul 做分布式节点发现和注册还有心跳检查,你随时可以看到其他的节点的状况。