[Zope-DB] ZODB/ZEO question.

Willadsens aagg at comcast.net
Fri Apr 1 15:13:28 EST 2005


>
> Ah, so you're using ZODB in a non-Zope context? If so, then you should 
> probably be using zodb-dev at zope.org and not this list. This list is 
> actually for relational database related stuff that has to do with zope.

Yes. Sorry I did not clarify that point. This list has been interesting 
anyway.

>
> In any case, I've never heard of using a sempahore in this instance, 
> and that would effectively make your application single threaded.
> I'd suggest building a mechanism that retries the ConflictError'ing code.
>
> Can you give us more detail about what it is you're doing that's 
> causing the ConflictErrors to be raised?


Sure.
Here is (1) the original trace, failing on the commit:

Traceback (most recent call last):
 File "DBClient_test.py", line 35, in ?
   dcdb.commit()
 File "/home/gloria/Restaurant_project/db_work/ZODB_access.py", line
164, in commit
   get_transaction().commit()
 File "/usr/local/lib/python2.4/site-
packages/transaction/_transaction.py", line 293, in commit
   self._commitResources(subtransaction)
 File "/usr/local/lib/python2.4/site-
packages/transaction/_transaction.py", line 334, in _commitResources
   rm.commit(self)
 File "/usr/local/lib/python2.4/site-packages/ZODB/Connection.py", line
610, in commit
   raise ConflictError(object=obj)
ZODB.POSException.ConflictError: database conflict error (oid 0x00,
class persistent.mapping.PersistentMapping)



Here are my code snippets from a ZODB class wrapper I wrote.

(2) the commit method:
    def commit(self):
        ''' This is necessary if a mutable object has changed. '''
        self._p_changed = True
        ''' I don't know why this is necessary as well, but it seems 
that the only
            way to get ZODB to detect a change is to reset the root to 
itself.
            This code also strips out duplicate entries from lists.
            We have to know it is a list to do so, and we're trusting 
that the type
            is correct.
        '''
        if(self.type == '[]'):
            try:
                self.root[self.db_name] = list(set(self.root[self.db_name]))
            except:
                self.root[self.db_name] = self.root[self.db_name]
        else:
            self.root[self.db_name] = self.root[self.db_name]
        get_transaction().commit()

(3) the test function, where I set globals to the DB list values, 
append, print, and repeat:

global dcdb
dcdb=ZODBData("defined_categories")
dcdb.openClient(type='[]')

global dmdb
dmdb=ZODBData("defined_measurements")
dmdb.openClient(type='[]')

globals.defined_categories=set(dcdb.root_key)
globals.defined_measurements=set(dmdb.root_key)

counter=0
while(True):
    try:
        print "***************"
        print "defined_categories:"
        print sorted(globals.defined_categories)
        print "defined_measurements:"
        print sorted(globals.defined_measurements)
        x='XP_Client_' + str(counter)
        dmdb.root_key.append(x)
        dcdb.root_key.append(x)
        dcdb.commit()
        dmdb.commit()
        globals.defined_categories=set(dcdb.root_key)
        globals.defined_measurements=set(dmdb.root_key)
        time.sleep (5)
        counter += 1
    except:
        good_trace.print_exc_plus()
        dcdb.close()
        del dcdb
        dmdb.close()
        del dmdb
   
        gc.collect()


I am running the exact same code on all platforms simultaneously.

If you can see any flaw in the ZODB usage, I would appreciate your comments.
Thank you for your time,
Gloria




More information about the Zope-DB mailing list