Mysql字段没有索引,通过where x = 3 for update是使用什么级别的锁

没有索引时,FOR UPDATE 会锁住整个表

现在,你正在一本一本地翻看所有书,寻找“维修中”的书,并且你对管理员说:“在我清点和修改完之前,别人不能动这些书,也不能往这个范围里加新书!

  • 问题1:如何锁住你找到的“维修中”的书?
    你每找到一本“维修中”的书,就给它贴上一个“正在处理,请勿触碰”的标签(行级排他锁)。

  • 问题2:如何防止别人“往这个范围里加新书”?
    这是最关键的。因为你没有“状态”的目录卡片(没有索引),你不知道“维修中”的书在图书馆的哪个具体位置。它们可能散落在图书馆的任何角落。

    • 你无法像有索引那样,只锁住“计算机类”书架的某个空位(间隙锁)。
    • 你正在全图书馆地毯式搜索。
    • 如果允许其他管理员在你搜索的时候,随便往任何一个空书架上放一本新的“维修中”的书,那么你就会遇到“幻读”——你清点完后,发现多出了几本你没见过的“维修中”的书。

唯一的办法就是:

为了确保在你搜索和处理期间,没有任何新的“维修中”的书被偷偷放进来,图书馆管理员只能宣布:

“暂停营业!所有人都不能动任何书,也不能放新书进来,直到这位管理员清点完毕!”

这就是表级排他锁。它锁住了整个图书馆,确保了在你操作期间,没有任何新的“维修中”的书能够被插入,从而彻底避免了幻读。

总结一下:

WHERE 条件中的字段没有索引时,数据库无法精确地定位和锁定数据范围。为了满足 FOR UPDATE 语句防止幻读的要求,它不得不采取最保守、最安全的策略——锁定整个表。这就像为了防止一只老鼠跑进屋子,你把整个房子的大门都锁死了。虽然有效,但代价是牺牲了其他人的自由(并发性)。

所以,为了提高数据库的效率和并发性,对于那些经常用于 WHERE 条件,特别是用于 FOR UPDATE 的字段,强烈建议创建索引。

你可能感兴趣的:(Mysql字段没有索引,通过where x = 3 for update是使用什么级别的锁)