TiDB的悲观事务,在写写冲突的情况下,会自动重试吗?

为提高效率,请提供以下信息,问题描述清晰能够更快得到解决:

【TiDB 版本】
4.0.8
【问题描述】


这张图片是截取TiDB官网, 我在想如果悲观事务都会重试, 那岂不是跟乐观事务一样了么? 也会因为重试而导致性能下降。还有重试在乐观事务下默认关闭, 那么在悲观事务下是默认行为吗?


若提问为性能优化、故障排查类问题,请下载脚本运行。终端输出的打印结果,请务必全选并复制粘贴上传。

同样引用两段官网的文档作为参考:
使用悲观事务模型时,autocommit 事务首先尝试使用开销更小的乐观事务模式提交。如果发生了写冲突,重试时才会使用悲观事务提交。所以 tidb_retry_limit = 0 时,autocommit 事务遇到写冲突仍会报 Write Conflict 错误。
变量 tidb_disable_txn_auto_retry 和 tidb_retry_limit 仅适用于乐观事务,不适用于悲观事务。

2赞

乐观事务冲突才会有重试的机制。
悲观事务冲突肯定是进行锁等待,等到资源释放后在继续执行事务,除非死锁。
我认为这个地方应该是悲观模型下,autocommit自动提交时为了节省,先采用乐观事务,遇见冲突,于是使用悲观事务进行重试,进行悲观事务后,就不需要再进行重试了。

2赞

https://docs.pingcap.com/zh/tidb/v4.0/troubleshoot-lock-conflicts#其他锁相关错误

pessimistic lock retry limit reached

在冲突非常严重的场景下,或者当发生 write conflict 时,乐观事务会直接终止,而悲观事务会尝试用最新数据重试该语句直到没有 write conflict。因为 TiDB 的加锁操作是一个写入操作,且操作过程是先读后写,需要 2 次 RPC。如果在这中间发生了 write conflict,那么会重试。每次重试都会打印日志,不用特别关注。重试次数由 pessimistic-txn.max-retry-count 定义。