Problems with ZODB, I can not persist and object accessed from 2 threads

dieter dieter at handshake.de
Tue May 6 07:03:08 EDT 2014


Ariel Argañaraz <arielin82 at gmail.com> writes:

> Hello, I am sorry I am stuck in this. And I need some help
>
> I want to persist an Object with ZODB, the object can be accessed from 2
> different threads. The ZODB manual says:
>
> A multi-threaded program should open a separate Connection instance for
> each thread. Different threads can then modify objects and commit their
> modifications independently.
>
> But there isn't an example of how to create a connection for each thread.
> Can someone tell me how to connect to the same DB from 2 threads??

You create a connection in the second thread in the same way
as you have created/opened it in the first thread (unless
something has done this automatically for you; in this case,
you must learn how this something has opened it).

Usually, you have one datebase (or more) (let's call it "db").
Then you open a connection to this database by "conn = db.open()".


The database (we have called it "db") is global to all threads.
Each thread must open (and maybe close) its own connection to the
global database. You must never share the same connection or
objects loaded via the connection between threads - very weird
(and apparently non-deterministic) errors can result.


Do not forget to "commit/abort" transactions, in order that
modifications done in one thread become visible in other threads.

Note that a connection "sees" the state of an object as it has
been when the transaction has started (note that transactions
are by default bound to threads -- thus each thread has its own
(independent) transactions). A transaction starts when
the former transaction has been "committed/aborted". Thus,
in order to see changes, it thread may need to "commit/abort" its
transaction even if it itself has changed nothing.

> ...
> I attached an example of what I am trying to do.
>
> And I get this error.
>
> Traceback (most recent call last):
>  File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
>    self.run()
>  File "/usr/lib/python2.7/threading.py", line 763, in run
>    self.__target(*self.__args, **self.__kwargs)
>  File "main.py", line 33, in thread_1
>    storage = FileStorage("/tmp/asdasd.fs")
>  File "/usr/lib/python2.7/site-packages/ZODB/FileStorage/FileStorage.py",
> line 164, in *_init_*
>    self._lock_file = LockFile(file_name + '.lock')
>  File "/usr/lib/python2.7/site-packages/zc/lockfile/__init__.py", line 84,
> in *_init_*
>    _lock_file(fp)
>  File "/usr/lib/python2.7/site-packages/zc/lockfile/__init__.py", line 59,
> in _lock_file
>    raise LockError("Couldn't lock %r" % file.name)
> LockError: Couldn't lock '/tmp/asdasd.fs.lock'

You try to open the database a second time -- this is only possible
in case you a using ZEO and a "ZEOClient" (not "FileStorage").
But, there is no need to open the database in each thread. The
database can be shared across all your threads.
Only the database connections must be thread local.




More information about the Python-list mailing list