MariaDB 中的行级锁
Posted
技术标签:
【中文标题】MariaDB 中的行级锁【英文标题】:row-level locks in MariaDB 【发布时间】:2020-12-17 07:32:11 【问题描述】:问题是,当 Session 1 尝试更新表 X 时,该表被锁定。
我需要的是只锁定 Session 1 尝试更新的行,而 Session 2 可以同时访问或更新其他行。
会话 1:update X set a=1994 where b =2 //I want to lock only row where b=2, not the whole table X
会话 2:update X set a=1951 where b =1 //I need it to work
PS:
我无权访问应用程序的代码,我需要 在数据库中配置它。autocommit=1
我正在使用innodb_version: 5.5.35-MariaDB-33.0
【问题讨论】:
【参考方案1】:假设 mariadb 的 innodb 实现作为 mysql 工作,您可以使用 mysql 手册中的 15.7.3 Locks Set by Different SQL Statements in InnoDB 部分来确定您需要做什么(重点是我的):
锁定读取、UPDATE 或 DELETE 通常会在 SQL 语句处理过程中扫描的每条索引记录上设置记录锁。语句中是否存在将排除该行的 WHERE 条件并不重要。 InnoDB 不记得确切的 WHERE 条件,而只知道扫描了哪些索引范围。
...
如果您没有适合您的语句的索引并且 MySQL 必须扫描 整个表处理语句,表的每一行 被锁定,从而阻止其他用户对 桌子。 创建良好的索引很重要,这样您的查询才能做到 不会不必要地扫描很多行。
因此,请在您的表上创建适当的索引,以免这些索引被锁定。
【讨论】:
我正在使用jbpm的数据库,这里是DDL script,它包含适当的索引,但是我遇到了这个问题。 很抱歉,我无法为您调试这么大的数据库结构 - 特别是因为我不知道查询,也不知道您遇到的问题是哪个表!我想说,如果您遇到锁定问题,那么您的索引可能没有您想象的那么好。 所以我的理解是,一旦索引设置正确,行锁级别默认工作,数据库上没有其他配置? 行级锁也可以在没有索引的情况下工作,只是可能会锁定整个表,而不仅仅是几行 - 正如您所发现的! 要将此答案与问题联系起来,您需要INDEX(b)
。以上是关于MariaDB 中的行级锁的主要内容,如果未能解决你的问题,请参考以下文章
[数据库事务与锁]详解五: MySQL中的行级锁,表级锁,页级锁