<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>聊聊 on 庞玉栋个人博客</title><link>https://pangyd.com/tags/%E8%81%8A%E8%81%8A/</link><description>Recent content in 聊聊 on 庞玉栋个人博客</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Tue, 09 Jan 2018 12:24:13 +0800</lastBuildDate><atom:link href="https://pangyd.com/tags/%E8%81%8A%E8%81%8A/index.xml" rel="self" type="application/rss+xml"/><item><title>聊聊分布式事务，再说说解决方案</title><link>https://pangyd.com/post/145/</link><pubDate>Tue, 09 Jan 2018 11:31:21 +0800</pubDate><guid>https://pangyd.com/post/145/</guid><description>&lt;p>&lt;br>&lt;/p>&lt;h3>前言&lt;/h3>&lt;p>&lt;br>&lt;/p>&lt;p>分布式事务是企业集成中的一个技术难点，也是每一个分布式系统架构中都会涉及到的一个东西，特别是在微服务架构中，几乎可以说是无法避免，本文就分布式事务来简单聊一下。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;h3>数据库事务&lt;/h3>&lt;p>&lt;br>&lt;/p>&lt;p>在说分布式事务之前，我们先从数据库事务说起。 数据库事务可能大家都很熟悉，在开发过程中也会经常使用到。但是即使如此，可能对于一些细节问题，很多人仍然不清楚。比如很多人都知道数据库事务的几个特性：原子性(Atomicity )、一致性( Consistency )、隔离性或独立性( Isolation)和持久性(Durabilily)，简称就是ACID。但是再往下比如问到隔离性指的是什么的时候可能就不知道了，或者是知道隔离性是什么但是再问到数据库实现隔离的都有哪些级别，或者是每个级别他们有什么区别的时候可能就不知道了。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>本文并不打算介绍这些数据库事务的这些东西，有兴趣可以搜索一下相关资料。不过有一个知识点我们需要了解，就是假如数据库在提交事务的时候突然断电，那么它是怎么样恢复的呢？ 为什么要提到这个知识点呢？ 因为分布式系统的核心就是处理各种异常情况，这也是分布式系统复杂的地方，因为分布式的网络环境很复杂，这种“断电”故障要比单机多很多，所以我们在做分布式系统的时候，最先考虑的就是这种情况。这些异常可能有 机器宕机、网络异常、消息丢失、消息乱序、数据错误、不可靠的TCP、存储数据丢失、其他异常等等…&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>我们接着说本地事务数据库断电的这种情况，它是怎么保证数据一致性的呢？我们使用SQL Server来举例，我们知道我们在使用 SQL Server 数据库是由两个文件组成的，一个数据库文件和一个日志文件，通常情况下，日志文件都要比数据库文件大很多。数据库进行任何写入操作的时候都是要先写日志的，同样的道理，我们在执行事务的时候数据库首先会记录下这个事务的redo操作日志，然后才开始真正操作数据库，在操作之前首先会把日志文件写入磁盘，那么当突然断电的时候，即使操作没有完成，在重新启动数据库时候，数据库会根据当前数据的情况进行undo回滚或者是redo前滚，这样就保证了数据的强一致性。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>接着，我们就说一下分布式事务。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;h3>分布式理论&lt;/h3>&lt;p>&lt;br>&lt;/p>&lt;p>当我们的单个数据库的性能产生瓶颈的时候，我们可能会对数据库进行分区，这里所说的分区指的是物理分区，分区之后可能不同的库就处于不同的服务器上了，这个时候单个数据库的ACID已经不能适应这种情况了，而在这种ACID的集群环境下，再想保证集群的ACID几乎是很难达到，或者即使能达到那么效率和性能会大幅下降，最为关键的是再很难扩展新的分区了，这个时候如果再追求集群的ACID会导致我们的系统变得很差，这时我们就需要引入一个新的理论原则来适应这种集群的情况，就是 CAP 原则或者叫CAP定理，那么CAP定理指的是什么呢？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;h4>CAP定理&lt;/h4>&lt;p>&lt;br>&lt;/p>&lt;p>CAP定理是由加州大学伯克利分校Eric Brewer教授提出来的，他指出WEB服务无法同时满足一下3个属性：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;ul>&lt;li>&lt;p>一致性(Consistency) ： 客户端知道一系列的操作都会同时发生(生效)&lt;/p>&lt;/li>&lt;li>&lt;p>可用性(Availability) ： 每个操作都必须以可预期的响应结束&lt;/p>&lt;/li>&lt;li>&lt;p>分区容错性(Partition tolerance) ： 即使出现单个组件无法可用,操作依然可以完成&lt;/p>&lt;/li>&lt;/ul>&lt;p>&lt;br>&lt;/p>&lt;p>具体地讲在分布式系统中，在任何数据库设计中，一个Web应用至多只能同时支持上面的两个属性。显然，任何横向扩展策略都要依赖于数据分区。因此，设计人员必须在一致性与可用性之间做出选择。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>这个定理在迄今为止的分布式系统中都是适用的！&amp;nbsp;为什么这么说呢？&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>这个时候有同学可能会把数据库的2PC（两阶段提交）搬出来说话了。OK，我们就来看一下数据库的两阶段提交。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>对数据库分布式事务有了解的同学一定知道数据库支持的2PC，又叫做 XA Transactions。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>MySQL从5.5版本开始支持，SQL Server 2005 开始支持，Oracle 7 开始支持。&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;p>其中，XA 是一个两阶段提交协议，该协议分为以下两个阶段：&lt;/p>&lt;p>&lt;br>&lt;/p>&lt;ul>&lt;li>&lt;p>第一阶段：事务协调器要求每个涉及到事务的数据库预提交(precommit)此操作，并反映是否可以提交.&lt;/p>&lt;/li>&lt;li>&lt;p>第二阶段：事务协调器要求每个数据库提交数据。&lt;/p>&lt;/li>&lt;/ul>&lt;p>&lt;br>&lt;/p>&lt;p>其中，如果有任何一个数据库否决此次提交，那么所有数据库都会被要求回滚它们在此事务中的那部分信息。这样做的缺陷是什么呢? 咋看之下我们可以在数据库分区之间获得一致性。&lt;/p></description></item></channel></rss>