关于8.1.2中行锁的预期表现

【 TiDB 使用环境】测试环境
【 TiDB 版本】
【复现路径】两个事务中人为制造行锁
【遇到的问题:问题现象及影响】当事务1中对id=2进行update并且不提交,在事务2中如果对同一行也进行update,发现如果是行纪录的值完全不变则不会被锁住,只有修改为不同值才会被锁住。这和mysql中表现不一样。想问下这是预期结果吗?

这不是对的吗?没更新到数据锁什么行

mysql中即便值相同的更新,也会锁住这一行,涉及到覆写问题。那是不是可以理解tidb中相同值就不会覆盖写了

不对啊,你第一步没用事务,这部已经提交了吗?

1 个赞

事务2没看到有开启事务的命令呢

TiDB 默认采用乐观事务模式。在乐观事务模式下,TiDB 不会在事务开始时立即加锁,而是在事务提交时检测冲突。如果事务 1 对某行数据进行了更新但未提交,事务 2 对同一行数据进行更新时,只有在事务 2 提交时才会检测到冲突。如果事务 2 的更新内容与事务 1 相同,则不会触发冲突检测,因此不会被锁住

TiDB 默认采用乐观事务模式。

你不知道就不要强答。8.1.2怎么会默认乐观事务?

https://docs.pingcap.com/zh/tidb/stable/system-variables#tidb_txn_mode

  • 这个变量用于设置事务模式。TiDB v3.0 支持了悲观事务,自 v3.0.8 开始,默认使用悲观事务模式

你差不多一点。那怕查一查呢?

:thinking:事务一开启了,不应该是事务一行锁,然后事务2不开启事务,应该也不能修改数据的吧。

表结构中id是pk or uk:

session1:
begin;
update tab set col=‘aaaaaa’ where id = 2; #不提交事务

session2:
begin;
update tab set col=‘bbbbbb’ where id = 2; 锁的特定默认会卡住,这是锁阻塞

你想模拟的是这个现象吧

session2,没有begin,应该也会卡住。因为session已经锁住了。

也对,session1已经占用着行锁呢

我自己试了下,有begin的情况下,事务2是能锁住的。

版本是

Release Version: v7.1.3-serverless

8.1.2 playground

update 大致上会先 select old snapshot data 然后替换 set 值再写回 new shapshot data,这里的特殊情况就是 set 值和 old 值一样的话,会跳过后续流程直接返回成功

如果你做个压力测试会发现,重复 set 相同值的情况下,tidb 压满了 tikv 还很空闲

另外单独的 update where id = ? 估计会走 async commit 乐观事务,可以看下监控 async commit 面板和事务面板