[ZODB-Dev] How to update an object in a multithreading application?

Marius Gedminas marius at gedmin.as
Mon Mar 19 20:36:57 UTC 2012


On Mon, Mar 19, 2012 at 02:04:34PM -0300, Sebastian Wain wrote:
> I am updating an item in a separated thread but when it finishes the new
> value is not updated in the same object in the main thread.
> 
>  
> 
> In the example below root['counter'] starts in 0, is incremented in the new
> thread but it remains in 0 in the main thread.
> 
>  
> 
> #!/usr/bin/python
> 
>  
> 
> from ZODB.FileStorage import FileStorage
> 
> from ZODB.DB import DB
> 
> from BTrees.OOBTree import OOBTree
> 
> import transaction
> 
> from threading import Thread
> 
> import persistent
> 
>  
> 
> class MyThread(Thread):
> 
>    def __init__(self, db):
> 
>       Thread.__init__(self)
> 
>       self.db = db
> 
>  
> 
>    def run(self):
> 
>       self.connection = self.db.open(transaction.TransactionManager())

This looks unnecessarily complicated.  Just use db.open(), transaction.begin(),
transaction.commit() -- these functions always use a thread-local transaction.

>       self.root = self.connection.root()
> 
>  
> 
>       print "Starting thread"
> 
>       self.connection.transaction_manager.begin()
> 
>       self.root["counter"] += 1
> 
>       self.connection.transaction_manager.commit()
> 
>       print "self.root['counter'] =", self.root['counter']
> 
>  
> 
>  
> 
> filename = 'test.fs'
> 
>  
> 
> storage = FileStorage(filename)
> 
> db = DB(storage)
> 
> connection = db.open()
> 
>  
> 
> root = connection.root()
> 
> if 'counter' not in root:
> 
>    transaction.begin()
> 
>    root['counter'] = 0
> 
>    transaction.commit()
> 
>  
> 
> thread = MyThread(db)
> 
> thread.start()
> 
>  
> 
> thread.join()
> 
>  
> 
> print "*** After ***"

As Alan said, you need a connection.sync() here.

I believe calling transaction.begin() again at this point would also do
that (just remember that transaction.begin() implicitly aborts the
previous transaction, so don't do that if you have uncommitted changes
you want to keep).

> print "root['counter'] =", root['counter']

Marius Gedminas
-- 
This is, or so I'm told, a classic book. I can see why. It is long and it
requires a great effort to finish it. If you go through a great effort to
suffer for a long time, you are allowed to sneer at people who can't be
bothered. That's the surest sign of classic art.
		-- Lars Wirzenius
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://mail.zope.org/pipermail/zodb-dev/attachments/20120319/4cb08389/attachment.sig>


More information about the ZODB-Dev mailing list