前阵子从支付宝转账1万块钱到余额宝,这是日常生活的一件普通小事,但作为互联网研发人员的职业病,我就思考支付宝扣除1万之后,如果系统挂掉怎么办,这时余额宝账户并没有增加1万,数据就会出现不一致状况了。 上述场景在各个类型的系统中都能找到相似影子,比如在电商系统中,当有用户下单后,除了在订单表插入一条记录外,对应商品表的这个商品数量必须减1吧,怎么保证?!在搜索广告系统中,当用户点击某广告后,除了在点击事件表中增加一条记录外,还得去商家账户表中找到这个商家并扣除广告费吧,怎么保证?!等等,相信大家或多或多少都能碰到相似情景。 这些问题本质上都可以抽象为:当一个表数据更新后,怎么保证另一个表的数据也必须要更新成功。 1 本地事务还是以支付宝转账余额宝为例,假设有 支付宝账户表:A(id,userId,amount) 余额宝账户表:B(id,userId,amount) 用户的userId=1; 从支付宝转账1万块钱到余额宝的动作分为两步: 1)支付宝表扣除1万:update A set amount=amount-10000 where userId=1; 2)余额宝表增加1万:update B set amount=amount 10000 where userId=1; 如何确保支付宝余额宝收支平衡呢?有人说这个很简单嘛,可以用事务解决。
如果系统规模较小,数据表都在一个数据库实例上,上述本地事务方式可以很好地运行,但是如果系统规模较大,比如支付宝账户表和余额宝账户表显然不会在同一个数据库实例上,他们往往分布在不同的物理节点上,这时本地事务已经失去用武之地。 既然本地事务失效,分布式事务自然就登上舞台。 2 分布式事务两阶段提交协议两阶段提交协议(Two-phase Commit,2PC)经常被用来实现分布式事务。一般分为协调器C和若干事务执行者Si两种角色,这里的事务执行者就是具体的数据库,协调器可以和事务执行器在一台机器上。 1) 我们的应用程序(client)发起一个开始请求到TC; 2) TC先将 |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|