# 分布式事务

__*分布式事务*__
__*Lock*__
__*Default*__
__*Write*__
__*start timestamp*__
__*commit timestamp*__
__*startTS*__
__*start_ts*__
__*commitTS*__
__*commit_st*__

![left](./student-guide/diagram/PercolatorTiKV01_zh_001_20220511.png)
-------------------------------------------------------------
学习完和 TiKV 的数据库持久化息息相关的 RocksDB 以后,我们一起来看一下 TiKV 的另一个功能实现,那就是分布式事务。

如果我们要同时操作多行数据,而这些数据落在不同的 Region 上面（甚至可能在不同的 TiKV 上）,为了保证操作的一致性,我们就需要分布式事务。

分布式事务要解决的问题是,比如我们需要同时将 < 1,Tom > 改为 < 1,Jack > ,< 2,Andy > 改为 < 2, Candy > （ < 员工编号,员工姓名 > 的 key - value ）,而 < 1,Tom > 和 < 2,Andy > 存储在不同的 Region 甚至 TiKV 上,那么当操作结束之后,有可能会出现,< 1,Tom > 改为 < 1,Jack >  成功,< 2,Andy > 改为 < 2, Candy > 失败或者反之。这样就破坏了事务的原子性,下面我们看看 TiDB 如何解决这个问题。

TiDB 参考了 Google 的 Percolator,对 2PC（ 两阶段提交 ） 进行了优化,来提供分布式事务支持,下面我们看一下具体实现:
1. 整个数据库需要有一个全局唯一和单调递增的 timestamp 来标识事务的开始时间 start timestamp (startTS / start_ts) 和提交时间 commit timestamp (commitTS / commit_st),这个 timestamp 由 PD 来提供。
2. Percolator 使用了 RocksDB 实例中的三个列族,也就是 column family (CF) 来存储数据、事务和锁信息。它们分别是:Lock,Default 和 Write。比如,我们写入 < 3, Frank >, 会将 key = 3 的锁（lock）记录到 Lock 列族（CF）中,将值 "3" 和 "Frank" 放到 Default 中,如果成功提交了（ committed ）,会在 Write  列族（CF）中进行记录,并删除掉锁信息。
接下来,我们会看一下 Percolator 的具体流程。