问题描述
我有一个带有一些实体的黑胶唱片空间,这些实体通过一些应用程序逻辑相互链接。任何实体的插入/更新也需要一些计算和链接实体的更新。
假设我们有一些带有 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 秒之间变化!所以,显然我有一些存储锁或类似的东西。
问题:
-
这怎么会发生呢?我以为 Tarantool 是一个线程,所以如果我调用
updateEntity()
,那么updateEntity()
的另一个调用只有在第一个完成后才能进行? -
我可以使用纤程来解决这个问题,将每个
updateEntity()
称为不同的纤程,并使用cK
实体进行所有内部操作,例如事务吗?还是我误解了纤维的用途? -
也许是其他地方出了问题,我错过了什么?
解决方法
Vinyl 引擎默认支持多版本并发控制,您可以阅读here 了解更多详情