知识库

共享与独占事务锁

本文档描述了事务视角下的共享锁的含义,以及共享锁和独占锁之间的区别。

“共享锁”表示多个事务可以同时持有同一把锁,其中“同一把锁”是资源类型和资源 ID 的组合。例如,对于节点资源类型,资源 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

Shared Lock

上述 Cypher MATCH 语句修改了节点,因此在节点上获取了一个独占锁。SHARED LABEL 锁用于数据库的模式。它们将阻止其他事务以涉及这些标签的方式修改模式,例如在 Actor 标签上创建新的唯一性约束。

其他说明

  • 如果该节点或关系存在共享锁,则无法获取独占锁。

  • 尝试使用独占锁修改节点的事务将等待任何现有的独占锁释放,然后才能获取。因此,锁获取时间发挥作用,控制在获取锁失败时超时的时间,可在 neo4j.conf 中通过dbms.lock.acquisition.timeout配置。

  • 事务最大运行时间的限制可在 neo4j.conf 中通过dbms.transaction.timeout配置,可用于在指定时间范围内释放事务获取的任何独占和共享锁。