共享锁与排他事务锁
本文档描述了事务眼中的共享锁含义以及共享锁与排他锁之间的区别。
“共享锁”意味着多个事务可以同时持有同一个锁,其中“同一个锁”是资源类型和资源 ID 的组合。例如,对于 NODE 资源类型,资源 ID 就是节点 ID。因此,多个事务可以共享该锁。这与排他锁形成对比,排他锁在任何给定时间只能由一个事务持有。因此它们是排他的。所以一个共享锁可以有多个持有者,而一个排他锁只能有一个持有者。共享锁主要用于索引或约束的读取目的。它们可以在查询规划和查询执行期间获取。
当我们想要读取某个对象,同时阻止其他事务写入或以其他方式修改该对象时,会获取共享锁。
在下面的截图中,Cypher 语句产生了一个共享锁
MATCH (p:Person)
WHERE p.name = 'Tom Hanks'
set p.award= 'Oscar'
以下代码可用于观察正在运行的另一个事务
在一个窗口中
MATCH (p:Person)
WHERE p.name = 'Tom Hanks'
SET p.award = 'Oscar'
with p
call apoc.util.sleep(200000)
RETURN p.award
在另一个窗口中
call dbms.listTransactions() yield currentQueryId , currentQuery
with currentQueryId, currentQuery
WHERE currentQuery STARTS WITH "MATCH (p:Person)"
WITH currentQueryId
call dbms.listActiveLocks(`currentQueryId`) YIELD mode, resourceType
RETURN mode, resourceType
上述 Cypher MATCH 语句修改了节点,因此在该节点上获取了排他锁。共享 LABEL 锁用于数据库的模式。它们将阻止其他事务以涉及这些标签的方式修改模式,例如在 Actor 标签上创建新的唯一性约束。
补充说明
-
如果节点或关系已存在共享锁,则无法获取排他锁。
-
试图使用排他锁修改节点的事务将等待任何现有排他锁被释放后才能获取锁。因此,锁获取时间开始发挥作用,它控制着在给定时间内未能获取锁时的超时设置,这可以在 neo4j.conf 中通过
dbms.lock.acquisition.timeout
配置。 -
最大事务运行时长的限制可以在 neo4j.conf 中通过
dbms.transaction.timeout
配置,这可以用作在指定时间范围内释放事务获取的任何排他锁和共享锁的手段。
此页面有帮助吗?