前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分布式事务系列--是选TCC还是SAGA

分布式事务系列--是选TCC还是SAGA

作者头像
IT云清
发布2019-03-20 09:41:32
3.1K0
发布2019-03-20 09:41:32
举报
文章被收录于专栏:IT云清IT云清
byteTCC框架,支持两种模式,一种是TCC模式,一种是SAGA模式,二者如何选择,是一个取舍问题,没有完美方案。

1.TCC模式

这种模式下,我们需要操作的目标字段,都要添加一个相关的冻结字段,try操作是操作冻结字段,cc操作时,将冻结的数值更新到目标字段。 示例如下:

代码语言:javascript
复制
  <!--try逻辑-->
  <update id="increaseMoney">
    UPDATE company SET frozen = frozen + #{money}
    WHERE id = #{id}
  </update>

  <!--confirm逻辑-->
  <update id="confirmIncreaseMoney">
    UPDATE company SET money = money + #{money},frozen = frozen - #{money}
    WHERE id = #{id}
  </update>

  <!--cancel逻辑-->
  <update id="cancelIncreaseMoney">
    UPDATE company SET frozen = frozen - #{money}
    WHERE id = #{id}
  </update>

2.SAGA模式

这种模式,是使用一个反向的业务操作,来撤销之前的业务操作。SAGA模式,try阶段直接操作目标字段,不需要使用冻结字段,和TCC模式相比,saga不需要confirm操作。

3.对比

设想一种场景:A->B,C,D。这种场景下,如果发生如下情况:

  • 1.B,C的try成功了,但是D的try失败了;
  • 2.此时另外的用户来读取BCD的值;
  • 3.ABCD进行回滚;

显然,不管是TCC还是SAGA模式,try出问题了,都会进入cancel阶段,但是,恰巧,在BC刚try成功D失败了,但是还未来得及回滚的情况下,有用户来读取BCD的值。

那么,这种情况下,使用TCC和SAGA,结果是不一样的。

在TCC中,由于try操作的是冻结字段,所以,其他用户在try和cancel的间隙来读数据,那么读的数据也是正确的,因为目标字段并没有发生改变。

在SAGA中,由于直接操作的目标字段,所以,try阶段,由于数据已经提交了,那么其他用户在try和cancel的间隙来读取数据,读到的数据,就是有问题的“脏数据”。

4.结论

1.TCC模式下
  • 缺点:开发麻烦,因为每个目标字段都需要一个冻结字段来支撑事务操作;
  • 优点:不存在上述脏数据的问题;
2.SAGA模式下
  • 缺点:数据没有很好的隔离,有脏数据的风险;
  • 优点:开发简单,不需要预留冻结字段;

当然,看起来只有在2PC模型下,才不存在这个“脏读风险”。

关于这个问题,推荐几篇文章看看: mysql的四种隔离级别 fescar锁设计和隔离级别的理解

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年03月15日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • byteTCC框架,支持两种模式,一种是TCC模式,一种是SAGA模式,二者如何选择,是一个取舍问题,没有完美方案。
  • 1.TCC模式
  • 2.SAGA模式
  • 3.对比
  • 4.结论
    • 1.TCC模式下
      • 2.SAGA模式下
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档