调用同一行的多个获取/更新时,Tarantool 存储锁定警告

问题描述

我有一个带有一些实体的黑胶唱片空间,这些实体通过一些应用程序逻辑相互链接。任何实体的插入/更新也需要一些计算和链接实体的更新。

假设我们有一些带有 id 的实体:e1,e2,e3 ... eN,eK

任何实体的更新都是由这样的代码完成的:

function updateEntity(eN) then
  space:update(eN)
  
  if eN linked to eK then
    -- Update linked entity eK and do some calculations.
    local eK = space:get('eK')

    -- Calculations using eK (time consuming)
    ...

    -- Modify linked entity eK
    space:update(eK)

    -- Some other calculations (time consuming)
    ...

    -- Using linked entity eK later somewhere else.
    local eKAgain = space.get('eK')
  end
end

updateEntity() 暴露给全局 (Box.schema.func.create('updateEntity') + rawset(_G,'updateEntity',updateEntity)) 并由 nodejs 连接器从外部调用

问题:
当我非常频繁地为与同一实体 updateEntity() 链接的实体调用 eK 时,我有多个警告,例如 get(['eK']) => ... took too long: 150.879 sec.
“卡住”时间的值在 1 到 1500 秒之间变化!所以,显然我有一些存储锁或类似的东西。

问题:

  1. 这怎么会发生呢?我以为 Tarantool 是一个线程,所以如果我调用 updateEntity(),那么 updateEntity() 的另一个调用只有在第一个完成后才能进行?

  2. 我可以使用纤程来解决这个问题,将每个 updateEntity() 称为不同的纤程,并使用 cK 实体进行所有内部操作,例如事务吗?还是我误解了纤维的用途?

  3. 也许是其他地方出了问题,我错过了什么?

解决方法

Vinyl 引擎默认支持多版本并发控制,您可以阅读here 了解更多详情