Is it time.time() a safe approach when creating content types on plone programatically?
I have to use _createObjectByType
on Plone. I have as an argument the id
of the object. Is it going to be safe, in this scenario, to create an id based on time.time()
to avoid collisions? Can two requests have exactly the same timestamp as shown by 开发者_如何学JAVAtime.time()
?
You'll be perfectly safe doing this, even in the unlikely event two requests are processed at exactly the same time, in event of a conflict the ZODB will raise a ConflictError and retry your request.
Responding to the discussion below:
On a single computer then by defition both transactions must overlap (you got the same result from time.time() in each thread.) ZODB is MVCC, so each thread sees a consistent view of the database as it was when the transaction began. When the second thread commits, a conflict error will be raised because it will write to an object that has changed since the beginning of the transaction.
If you have clients running on multiple computers then you need to think about the possibility of clock drift between the clients. For its transaction ids, ZODB chooses whichever is the greater of either the current timestamp or the last transaction id + 1.
However, perhaps you should consider not using a timestamp as an id at all, as it will lead to conflicts under heavy load, as all requests will want to create entries in the same BTree bucket. Picking ids randomly will eliminate almost all of the conflicts, but will lead to inefficiently filled BTrees. The recommended approach is for each thread that creates objects to start at a random point in the number space and create ids sequentially. If it finds that an id has already been used then it should randomly pick another point in the number space and start again from there. I believe zope.intid contains an implementation of this strategy.
精彩评论