[Zope] Unique incrementing IDs

Terrel Shumway tshumway@epicor.com
Tue, 14 Sep 1999 14:07:33 -0700


Thank you, Kevin, for your idea. I wanted to do the same thing, and your
idea worked wonderfully because of the transaction stuff that Mike
explained. 

I noticed, however, that using REQUEST.set, then passing REQUEST to
manage_changeProperties has a very nasty
side effect: All of the properties of the object may be changed, not just
newid. For example, if REQUEST happens to contain {"title": "new title"},
then your folder gets its title changed.

This is what I ended up doing:

folder id="repository"

    property next_id = 1

    property id_template = "doc-%06d"

    dtml-method "get_new_id" =
      <dtml-let id=next_id>
        <dtml-call "manage_changeProperties({'next_id': id + 1})">
        <dtml-return "id_template % id">
      </dtml-let>


Then I just call get_new_id whenever I want to get a unique id for a new
item in the repository folder.


-----Original Message-----
From: Michel Pelletier [mailto:michel@digicool.com]
Sent: Saturday, September 11, 1999 10:09 AM
To: Kevin Dangoor
Cc: zope@zope.org
Subject: Re: [Zope] Unique incrementing IDs


Kevin Dangoor wrote:
> 
> Hi,
> 
>     Since Zope is multithreaded, it seems like there could be a problem
> doing something like this:
> 
> <dtml-comment newid is a folder property>
> <dtml-call "REQUEST.set('newid', newid + 1)">
> <dtml-call "manage_changeProperties(REQUEST)">
> <dtml-call "REQUEST.set('id', newid)">
> <dtml-with "manage_addProduct['SomeProduct']">
> <dtml-call "ZClass_add(_.None, _)">
> </dtml-with>
> 
> It seems plausible that you might end up trying to create two objects with
> the same ID. This will obviously fail, but it would be nice if there was
an
> easy way to get the next ID sequentially like this. Am I correct in
assuming
> that there may be a condition where it tries to create two objects with
the
> same ID?

Yes.  This would cause the database to raise a 'ConflictError'.  If this
happes, one thread wins and one thread looses.  The looser's transaction
is completely aborted, and the loosers request is resubmitted in a whole
new transaction.  This works well to avoid the problem your thinking
about.

-Michel