首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >浅谈分布式开发环境下的事务一致性处理

浅谈分布式开发环境下的事务一致性处理

作者头像
攻城狮的那点事
发布2019-06-28 16:26:43
发布2019-06-28 16:26:43
7310
举报

有经验的Coder都知道,事务是在软件开发中至关重要,而在分布式开发环境下,事务的每个操作步骤是运行在不同机器上的服务。分布式事务处理的关键是必须有一种方法可以知道事务在任何地方所做的所有动作,提交或回滚事务的决定必须产生统一的结果(全部提交或全部回滚),从而保证最终数据的一致性。

现如今的大型互联网平台往往是由一系列分布式系统构成的,开发语言平台和技术栈也相对比较复杂,尤其是在SOA和微服务架构盛行的今天,一个看起来简单的功能,内部可能需要调用多个“服务”并操作多个数据库或分片来实现,情况往往会复杂很多。单一的技术手段和解决方案,已经无法应对和满足这些复杂的场景了。

在分布式系统中,同时满足CAP定律中的一致性 Consistency、可用性 Availability和分区容错性 Partition Tolerance三者是不可能的。在绝大多数的场景,都需要牺牲强一致性来换取系统的高可用性,系统往往只需要保证最终一致性。

数据一致性

强一致性: 当更新操作完成之后,任何多个后续进程或者线程的访问都会返回最新的更新过的值。这种是对用户最友好的,就是用户上一次写什么,下一次就保证能读到什么。根据 CAP 理论,这种实现需要牺牲可用性。

弱一致性: 系统并不保证后续进程或者线程的访问都会返回最新的更新过的值。系统在数据写入成功之后,不承诺立即可以读到最新写入的值,也不会具体的承诺多久之后可以读到。

最终一致性: 弱一致性的特定形式。系统保证在没有后续更新的前提下,系统最终返回上一次更新操作的值。在没有故障发生的前提下,不一致窗口的时间主要受通信延迟,系统负载和复制副本的个数影响。DNS 是一个典型的最终一致性系统。

场景应用

例如在线下单,涉及了几个子系统的业务处理。当客户点击下单时,首先会调用客户子系统获取和校验客户信息,然后再调用商品子系统获取当前商品库存、价格等相关信息,接下来再由订单子系统处理下单,下单成功再调商品模块扣减库存,调用客户模块业务更新客户优质度等,并调用消息系统生成相应消息发出通知。这一流程,如果各个子系统都正常服务,似乎没啥问题,但如果中间某个子系统出现故障,就会造成故障系统模块的数据无法同步处理,如果涉及重要数据,就必须让事务回滚。如果数据库采用分库分表,对不同数据库操作也必须引入分布式事务。

实现情况中,庞大的系统和复杂的环境,我们无法保证每个子系统时刻都无误运行。这时往往会考虑到孰轻孰重,一般会把重要的业务加入事务处理,对非必须业务不加入事务。

消息与最终一致性

本地消息表:需要额外建一个消息表,并记录消息发送状态。消息表和业务数据要在一个事务里提交,也就是说他们要在一个数据库里面。然后消息会经过MQ发送到消息的消费方。如果消息发送失败了,会进行重试发送。消息消费方接收到消息需要处理,并完成自己的业务逻辑。此时如果本地事务处理成功,表明已经处理成功了,如果处理失败,那么就会重试执行。如果是业务上面的失败,可以给生产方发送一个业务补偿消息,通知生产方进行回滚等操作。

一般生产方和消费方定时扫描本地消息表,把那些还没处理完成的消息或者失败的消息再发送一遍。如果有靠谱的自动对账补账业务逻辑,这种方案还是非常实用的。

如果做过第三方支付的小伙伴应该都知道,实现中最典型的例子就是 微信支付和支付宝支付成功后的回调。

优点: 一种非常经典的实现,避免了分布式事务,实现了最终一致性。在 .NET中 有现成的解决方案。

缺点: 消息表会耦合到业务系统中,如果没有封装好的解决方案,会有很多杂活需要处理。

TCC编程模式

所谓的TCC编程模式,也是两阶段提交的一种方式。TCC提供了一个编程框架,将整个业务逻辑分为三块:Try、Confirm和Cancel三个操作。以在线下单为例,Try阶段会去扣库存,Confirm阶段则是去更新订单状态,如果更新订单失败,则进入Cancel阶段,会恢复数据库操作。总之,TCC就是通过代码人为实现了两阶段提交,不同的业务场景所写的代码都不一样,复杂度也不一样,因此,这种模式并不能很好地被复用。这种业务逻辑在银行项目中体现的更多,如HSBC的项目。

总结

分布式事务,本质上是对多个系统、多个数据库的事务进行统一管理。事务控制分为:不控制、部分控制和完全控制。不控制是不需要引入分布式事务,部分控制是两阶段提交,包括上面提到的消息事务+最终一致性、TCC模式。而完全控制是完全实现两阶段提交。部分控制的好处是并发量和性能很好,缺点是数据一致性减弱了,完全控制则是牺牲了性能,保障了一致性,具体用哪种方式,最终还是取决于业务场景。作为技术人员,一定不能忘了技术是为业务服务的,不要为了技术而技术,针对不同业务进行技术选型是很重要的。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-04-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 攻城狮的那点事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档