# TiDB 数据库悲观锁 (C) DML 锁

![left](./student-guide/diagram/12-pessimistic-locking-03-01.png)

-------------------------------------------------------------
TiDB 数据库悲观锁

理解了 TiDB 数据库的事务流程，我们发现了一个问题，那就是我们的锁是在事务的 commit 阶段加上的。也就是说在事务开始时刻和事务提交时刻之前这段时间，我们一直不进行锁检测，这段时间默认事务的每行都没有锁，操作都会成功。提交的时候才会检查版本信息和锁信息，这种策略叫做乐观锁。它有一个特点，就是事务执行过程中永远不会因为锁冲突而回滚，但是提交的时候有可能发现冲突回滚。试想，一个执行了 20 分钟的长事务，只在提交的时候发现了冲突，回滚了，之前的 20 分钟操作就白做了。

与乐观锁对应就是悲观锁，它的特点是在事务中每操作一行（增、删、改）都会马上加锁，这样如果加锁的时候发现这行已经被其他事务锁住或者修改，那么事务就会阻塞或者回滚。这样做的好处就是可以在事务运行过程中马上发现冲突。

TiDB 实现悲观事务的方式很聪明而且优雅，我们仔细思考了 Percolator 的模型发现，其实我们只要将在客户端调用 Commit 时候进行两阶段提交这个行为稍微改造一下，将第一阶段上锁和等锁提前到在事务中执行 DML 的过程中不就可以了吗，就像这样：
