.markdown-body{word-break:break-word;line-height:1.75;font-weight:400;font-size:15px;overflow-x:hidden;color:#333}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{line-height:1.5;margin-top:35px;margin-bottom:10px;padding-bottom:5px}.markdown-body h1{font-size:30px;margin-bottom:5px}.markdown-body h2{padding-bottom:12px;font-size:24px;border-bottom:1px solid #ececec}.markdown-body h3{font-size:18px;padding-bottom:0}.markdown-body h4{font-size:16px}.markdown-body h5{font-size:15px}.markdown-body h6{margin-top:5px}.markdown-body p{line-height:inherit;margin-top:22px;margin-bottom:22px}.markdown-body img{max-width:100%}.markdown-body hr{border:none;border-top:1px solid #ddd;margin-top:32px;margin-bottom:32px}.markdown-body code{word-break:break-word;border-radius:2px;overflow-x:auto;background-color:#fff5f5;color:#ff502c;font-size:.87em;padding:.065em .4em}.markdown-body code,.markdown-body pre{font-family:Menlo,Monaco,Consolas,Courier New,monospace}.markdown-body pre{overflow:auto;position:relative;line-height:1.75}.markdown-body pre>code{font-size:12px;padding:15px 12px;margin:0;word-break:normal;display:block;overflow-x:auto;color:#333;background:#f8f8f8}.markdown-body a{text-decoration:none;color:#0269c8;border-bottom:1px solid #d1e9ff}.markdown-body a:active,.markdown-body a:hover{color:#275b8c}.markdown-body table{display:inline-block!important;font-size:12px;width:auto;max-width:100%;overflow:auto;border:1px solid #f6f6f6}.markdown-body thead{background:#f6f6f6;color:#000;text-align:left}.markdown-body tr:nth-child(2n){background-color:#fcfcfc}.markdown-body td,.markdown-body th{padding:12px 7px;line-height:24px}.markdown-body td{min-width:120px}.markdown-body blockquote{color:#666;padding:1px 23px;margin:22px 0;border-left:4px solid #cbcbcb;background-color:#f8f8f8}.markdown-body blockquote:after{display:block;content:""}.markdown-body blockquote>p{margin:10px 0}.markdown-body ol,.markdown-body ul{padding-left:28px}.markdown-body ol li,.markdown-body ul li{margin-bottom:0;list-style:inherit}.markdown-body ol li .task-list-item,.markdown-body ul li .task-list-item{list-style:none}.markdown-body ol li .task-list-item ol,.markdown-body ol li .task-list-item ul,.markdown-body ul li .task-list-item ol,.markdown-body ul li .task-list-item ul{margin-top:0}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:3px}.markdown-body ol li{padding-left:6px}.markdown-body .contains-task-list{padding-left:0}.markdown-body .task-list-item{list-style:none}@media (max-width:720px){.markdown-body h1{font-size:24px}.markdown-body h2{font-size:20px}.markdown-body h3{font-size:18px}}
大家好,我是南橘,从接触java到现在也有差不多两年时间了,两年时间,从一名连java有几种数据结构都不懂超级小白,到现在懂了一点点的进阶小白,学到了不少的东西。知识越分享越值钱,我这段时间总结(包括从别的大佬那边学习,引用)了一些平常学习和面试中的重点(自我认为),希望给大家带来一些帮助
这是消息中间件的文章,大家没有看过的可以跟着看一下
随着互联网应用的量级越来越大,单体应用架构越来越无法满足需求,所以,分布式集群架构就应运而生了。这几章,我们就来谈谈如何在分布式系统中实现事务的一致性。
CAP理论:一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项。
从客户端角度,多进程并发访问时,还有不同的一致性的划分:
1.强一致性:对于关系型数据库,要求更新过的数据能被后续的访问都能看到.
2.弱一致性:能容忍后续的部分或者全部访问不到。
3.最终一致性:经过一段时间后要求能访问到更新后的数据。
但是,在CAP理论中虽然说是三者只能满足两者,但实际情况是,在分布式场景中分区一定存在,即必须有分区容忍性对应的策略,之后才能在一致性和可用性间二者之间选择.所以对主流架构来说不是三选二,而是二选一,而我们今天要讲的柔性柔性事务,就是基于BASE理论,放弃实现强一致性,首先实现可用性和分区容忍性,进而实现最终一致性。
base是Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)三个短语的简写。base是对cap中一致性和可用性的权衡的结果。是根据cao理论演变而来,核心思想是即使无法做到强一致性,但是每个应用根据自身的业务特点,采用适当的方式来使系统达到最终与执行。
在阶段二中,协调者会根据各参与者的反馈情况来决定最终是否可以进行事务提交操作,正常情况下,包含以下两种可能:
步骤 | 执行事务提交 | 中断事务 |
---|---|---|
1 | 协调者向所有参与者节点发出Commit请求(发送提交请求) | 协调者向所有参与者节点发出Rollback请求(事务提交) |
2 | 参与者接收到Commit请求后,会正式执行事务提交操作,并在完成提交之后释放在整个事务执行期间占用的事务资源(反馈事务提交结果)。 | 参与者收到Rollback请求之后,会利用其在阶段一种记录的Undo信息来执行事务回滚操作,并在完成回滚之后释放在整个事务执行期间占用的资源(完成事务) |
3 | 参与者在完成事务提交之后,协调者发送Ack消息(发送回滚请求) | 参与者在完成事务回滚之后,向协调者发送Ack消息(事务回滚) |
4 | 协调者接收到所有参与者反馈的Ack消息后,完成事务(反馈事务回滚结果) | 协调者接收所有参与者反馈的Ack消息后,完成事务中断(中断事务) |
3PC 是在 2PC 阶段的改进版,将二阶段提交协议的 "提交事务请求" 过程一分为二。形成由CanCommit、PreCommit、doCommit三个阶段组成的事务处理协议。
步骤 | 执行事务预提交 | 中断事务 |
---|---|---|
1 | 协调者向所有参与者节点发出 preCommit 的请求,并进入 Prepared 阶段(发送预提交请求) | 协调者向所有参与者节点发出 abort 请求(发送中断请求) |
2 | 参与者接收到 preCommit 请求后,会执行事务操作,并将 Undo 和 Redo 信息记录到事务日志中(事务预提交) | 无论是收到来自协调者的 abort 请求,或者是在等待协调者请求过程中出现超时,参与者都会中断事务(中断事务) |
3 | 各参与者向协调者反馈事务执行的响应:如果参与者成功执行了事务操作,那么就会反馈给协调者 Ack 响应,同时等待最终的指令:提交 (commit) 或中止(abort) | |
步骤 | 执行事务 | 中断事务 |
---|---|---|
1 | 假设协调者处于正常工作状态,并且接收到来自所有参与者的 Ack 响应,则它将从 “预提交” 状态转换到 “提交” 状态,向所有参与者发送 doCommit 请求(发送提交请求) | 假设协调者处于正常工作状态,并且任意一个参与者向协调者反馈了 No 响应,或者在等待超时之后,协调者尚无法接收到所有参与者的反馈响应。则中断事务(发送中断请求) |
2 | 参与者接收到 doCommit 请求后,会正式执行事务提交操作,并在完成提交之后释放在整个事务执行期间占用的事务资源(事务提交)。 | 参与者接收到 abort 请求后,会利用其在阶段二中记录的 Undo 信息来执行事务回滚操作,并在完成回滚之后释放在整个事务执行期间占用的资源(事务回滚) |
3 | 参与者在完成事务提交之后,向协调者发送 Ack 消息(反馈事务提交结果) | 协调者接收到所有参与者反馈的 Ack 消息后,中断事务(中断事务) |
4 | 协调者接收到所有参与者反馈的 Ack 消息后,完成事务(完成事务) | |
进入阶段三,可能出现一些问题:
无论出现那种情况,参与者都无法及时接收到来自协调者的 doCommit 和 abort 请求,对于该问题,参与者都会在等待超时之后,继续进行事务提交。(会导致数据不一致性)
协调者调用所有参与者的try操作,并在活动管理器中登记所有参与者。当所有参与者服务的 try 操作都调用成功或者某个参与者服务的 try 操作失败,进入第二阶段。
这个阶段中,需要完成所有业务检查(一致性)、并且预留必须业务资源(准隔离性)。
活动管理器根据第一阶段的执行结果来执行 confirm 或 cancel 操作。
这个阶段中已经不需要做业务检查,因为Try阶段已经完成了业务检查,同时只使用Try阶段预留的业务资源来执行业务。
如果第一阶段所有 try 操作都成功,则活动管理器调用所有参与者的 confirm操作。
如果第一阶段有 try 操作失败,则调用所有参与者服务的 cancel 操作,同时释放Try阶段预留的业务资源
TCC事务的优点如下:
第二阶段 confirm 或 cancel 操作本身也是满足最终一致性的过程,在调用 confirm 或 cancel 的时候也可能因为某种原因(比如网络)导致调用失败,所以需要活动管理支持重试的能力,同时这也就要求 confirm 和 cancel 操作具有幂等性。
如果有些业务由于瞬时的网络故障或调用超时等问题,很多服务是依赖于外部系统的可用性情况,在一些重要的业务场景下还需要周期性的对账来保证真实的一致性。比如支付系统和银行之间每天日终是都会有对账过程。
简单介绍了一下柔性分布式事务 同时需要思维导图的话,可以联系我,毕竟知识越分享越香!