我必须在Plone上使用_createObjectByType
。我以对象的id
作为参数。在这种情况下,是否可以安全地创建基于time.time()
的ID以避免冲突?两个请求可以具有完全相同的时间戳,如time.time()
?
答案 0 :(得分:5)
即使在两个请求完全同时处理的情况下,即使发生冲突,ZODB也会引发ConflictError并重试您的请求,即使在极少数情况下同时处理两个请求,您也会非常安全。
回应以下讨论:
在一台计算机上然后通过定义两个事务必须重叠(你在每个线程中从time.time()获得相同的结果。)ZODB是MVCC,因此每个线程看到数据库的一致视图,就像它在交易开始了。当第二个线程提交时,将引发冲突错误,因为它将写入自事务开始以来已更改的对象。
如果您的客户端在多台计算机上运行,那么您需要考虑客户端之间时钟漂移的可能性。对于其事务ID,ZODB选择当前时间戳或最后一个事务id + 1中的较大者。
但是,也许您应该考虑不使用时间戳作为id,因为它会在重负载下导致冲突,因为所有请求都希望在同一BTree存储桶中创建条目。随机挑选ID将消除几乎所有的冲突,但会导致无效填充的BTrees。建议的方法是为每个创建对象的线程在数字空间中的随机点开始,并按顺序创建ID。如果它发现已经使用了id,那么它应该随机选择数字空间中的另一个点并从那里再次开始。我相信zope.intid包含了这种策略的实现。