[Zope] How to prevent concurrent access to the same object?

Richard Barrett R.Barrett@ftel.co.uk
Fri, 08 Feb 2002 16:16:06 +0000


At 20:40 08/02/2002 +0500, you wrote:
>Richard Barrett wrote:
>
>>At 11:12 08/02/2002 +0500, Alexei Ustyuzhaninov wrote:
>>
>>>Richard Barrett wrote:
>>>
>>> > At 10:15 06/02/2002 +0500, Alexei Ustyuzhaninov wrote:
>>> >
>>> >> Hi!
>>> >>
>>> >> Is it possible to make a zope object which doesn't allow simultaneous
>>> >> access to itself? I mean that if two users call methods of the same
>>> >> object then only one call will process at a time and the other one
>>> >> will wait untill the first call will finish. I tried to fix it up with
>>> >> unix semaphores but with no success.
>>> >
>>> >
>>> > Why do you want to do this so explicitly?
>>> >
>>> > I believe that Zope is inherently transactional and its own database
>>> > updates are performed atomically with transaction commit, abort,
>>> > rollback and retry apparatus built in.
>>>
>>>BTW is there any method to monitor zope transactions? My experience is
>>>that they have quite peculiar behaviour.
>>
>>How so peculiar?
>
>
>Well, let me share my story. I have a zope product which should be an 
>editor of some special files. The main window of the editor is divided 
>into two frames. The left frame is a menu which allows the user to choose 
>different views of the file. After choosing an option in the menu the 
>corresponding view will be shown in the right frame. Generation of the 
>view takes some time on the server and during this time the user can 
>choose another option in the menu. This will fire up another transaction 
>on the server which may be inconsistent with the unfinished previous one. 
>The reason is that both transactions affect the same file which is not 
>protected by the zope supervision.
>
>To prevent this situation I need to lock the second transaction untill the 
>first one will finish. And because both transactions perform as separate 
>unix processes I decided to use semaphores to synchronize them.  A 
>two-state semaphore is linked to every editable file. Ideally on entry a 
>process waits until the corresponding semaphore be turned off, then turns 
>it on itself, and turns off on entry. But this doesn't work in life. The 
>second process never gets the semaphore turned off. Seems like  it locks 
>the first process some other way and whole system is clinched. And that's 
>what is peculiar for me in zope: how (and why) future transactions affect 
>the previous ones?

I'm assuming these special files are in the host OS (UNIX ?) file system.

Let me suggest the following approach:

1. if you do not already have this, have a surrogate object in the ZODB for 
each of your special files in the file system. You can then use the 
transactability of ZODB over such objects to protect the external resource.

2. Have an integer attribute on these objects.

3. Immediately your server side code starts to process a request which 
changes the contents of the external file have it change the surrogate 
object attribute: increment it for instance.

4. This will create a write lock over the surrogate and in effect over the 
external file.

5. Any other transaction attempting to change the attribute will then be 
rolled back and retried. If all of your code plays together and always 
tries to modify the surrogate attribute first then multiple updates of the 
proxyied file are prevented.

6. Arrange all of the processing of a file to be performed while the lock 
is held, that is before the response is sent back to the browser for the 
request.

7. When you return a response to the browser, you can include the identity 
of the surrogate object and the value of the integer attribute on it 
associated with the file as a hidden input fields in a form which is used 
to make the user processing request.

8. If when the user selects an option (view of the file) this value is 
returned, it can be compared with the value of the object attribute when 
the request is received. If they do not match then your code can decide on 
whether to reject the processing request and return the revised data or do 
the requested processing.

>>> > That said, you might want to ask how to plug in your own commit,
>>> > rollback and retry code to zope's transaction commit and abort handlers
>>> > if you problem is to control updating of some external database from
>>> > zope code.
>>>
>>>I think you are right though I don't need sterling transactions in my 
>>>objects. I need simple locks.
>>>
>>>So, could somebody advice how to plug in extra code to the zope 
>>>transaction machinery?
>>
>>I do not know if it is still upd to date but you could try the material 
>>here: http://www.zope.org/Documentation/Developer/Models/ZODB/
>
>
>Thanks.
>
>--
>Alexei
>