# TSO 分配: 过程

__*TSO 分配过程*__

![`smart`](TSOAssignmentProcess_zh_001_20220509.png)
---------------------------------------------------------------
所有的 `TiDB` server 与 `PD` 交互的逻辑都是通过一个 `PD Client` 的线程模块进行的, 这个模块专门负责批量从 `PD` 获取 `TSO`, 工作流程大致流程如下:

1. `TSO` 请求者（事务）需要请求 `TSO` 时, 会先把请求发给 `PD Client`模块, `PD Client` 模块会立即返回一个 `tsFuture` 对象给的 `TSO` 请求者, 对应图中的 1号 和 2号。
2. `TSO` 请求者收到 `tsFuture` 以后缓存起来,马上开始执行 SQL 的解析和编译,解析和编译之后调用 `tsFuture` 的 wait 方法来等待 `TSO` 返回, 对应图中的 4号。
3. 同时, `PD Client` 则异步通过 `gRPC` 向 `PD` 获取 `TSO`, 这里要注意并不是一次 `TSO` 的请求对应发出后, `PD Client` 马上会向 `PD` 请求 `TSO`, 当同一时间段（极短）有大量的请求并发到达 `PD Client` 时, `PD Client` 会进行批处理,将这些请求作为一个批处理请求只发送一次,但是如果 PD Client 收到 `TSO` 请求的间隔较长,仍然会一条一条请求向 PD 发送的。对应图中:3 和 5。
4. `PD Client` 收到 `PD` 返回的 `TSO` 后, `PD Client` 尝试将 `TSO` 返回给对应的 `TSO` 请求者, 如果这个时候 `TSO` 请求者正好调用 `tsFuture` 的 `wait` 方法时, 则 `TSO` 请求者则获得了 `TSO`, 否则直到 `tsFuture` 的 `wait` 方法开始等待。对应图中的 6号。

综上所述, 整个 `TSO` 的分配是一个异步的过程。