分布式事务:乐观事务和悲观事务

前言

最近留意到了一款优秀的国产数据库tidb,研究了一下他们实现的分布式事务,属于二段提交(2PC)。tidb借鉴了 google 用于实现 big table 的分布式事务实践 Percolator 。下面会讲一下分布式事务的乐观和悲观锁。

悲观 or 乐观?

拿去餐厅用餐等位置的经历来举例

乐观者

这个时候餐厅应该不会很多人吧?我去先去看看排的队长不长,长我就先回家等等,不长我就去用餐了。

悲观者

这个时候餐厅应该会很多人吧?我先打个电话预约一下餐桌,免得到时候人多白跑一趟。

分析

不难发现,乐观者会先假设餐厅是相对空闲的一个状态,避免了占用资源但是暂时不使用的浪费资源现象。而悲观者会基于资源是相对繁忙的一个情况,会先对资源进行预约占用(上锁)。

乐观事务

下面来讲一下乐观事务的事务流程。在事务提交之前,会先把数据的 update/delete 操作缓存到内存。然后大体分为两个步骤完成事务提交。

Prewrite

把需要修改的 key 分为两部分:随机1个 primary 、其他作为 secondaries 。

  • 首先把 primary 上锁,会有两种情况上锁失败:
    • key 已经被上锁
    • 在本次事务开始时间戳(startTs)后,已经有过写操作,此处称为冲突(Conflict)。
  • 把 secondaries 用 primary key 类似的上锁方法上锁
上锁前

上锁后

Commit

Prewrite 完成之后,需要开始进行提交操作。

  • 提交 primary key:写入数据,记录事务提交时间戳(commitTs)。
  • 解开 primary key 的锁
  • 异步进行提交 secondaries key 操作。

重试

由于在 Prewrite 阶段有可能会产生失败,失败就会产生回滚和重试。在一些大事务当中,冲突率有可能非常高,导致频繁重试。此时需要引入悲观事务。

悲观事务

悲观锁事务其实整体流程都非常类似乐观锁事务。不同的是,把 prewrite 阶段的锁,提前到客户端开启事务中的DML语句当中。


乐观事务

悲观事务

版权声明

本文版权归作者所有,请勿私自转载文章,感谢!

参考

TiDB 最佳实践系列(三)乐观锁事务
TiDB 新特性漫谈:悲观事务

你可能感兴趣的:(分布式事务:乐观事务和悲观事务)