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 time.time()
?

- 13,029
- 20
- 64
- 103
1 Answers
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.

- 2,909
- 17
- 20
-
I was thinking exactly about the Conflict Error: if it is raised, how come it retries the request? Isn't the request lost? – Somebody still uses you MS-DOS Jun 30 '11 at 20:28
-
No, Plone(Zope actually) retries it because there was a conflict error so the request is not lost since Zope is the one handling the request. – vangheem Jun 30 '11 at 20:33
-
1i doubt that you will run into a conflict error situation. Instead one request will receive an exception about the ID being already in use. – Jul 01 '11 at 02:51
-
Laurence is right. With time.time() you can only have a collision when two requests are at exactly the same time. This will cause a ConflictError. – JC Brand Jul 01 '11 at 08:16
-
@Sentinel: Exactly. I was afraid of that. I've had this problem in the past (but not using time.time()). I want to know the reliability of time.time() in having unique ids in plone. – Somebody still uses you MS-DOS Jul 01 '11 at 14:15