SV: [ZODB-Dev] get_transaction

Magnus Heino magnus.heino@pleon.sigma.se
Fri, 30 Nov 2001 07:54:01 +0100


> > There's only one connection, you created two references to the same
> > object.
>
> OK, how about this:
>
> from ZODB import FileStorage, DB
>
> storage1 = FileStorage.FileStorage('/tmp/test-filestorage1.fs')
> db1 = DB( storage1 )
> conn1 = db1.open()
>
> storage2 = FileStorage.FileStorage('/tmp/test-filestorage2.fs')
> db2 = DB( storage2 )
> conn2 = db2.open()
>
> root1 = conn1.root()
> root2 = conn2.root()
>
> root1[1]=1
> root2[2]=2
> get_transaction().commit()
>
> :^)=
>
> ("Don't do that is not exactly an acceptable answer, either. ;) )

That's more like what I was trying to ask, thanks ;)

I found a simular question in
http://lists.zope.org/pipermail/zodb-dev/2000-September/000447.html too,
that never got an answer, I'll do some cut'n'paste;

-----

OK, I've played around a bit and I think I see how to have two
connections to the same database: it looks like I need a *single*
Storage object, because if I try to open two Storages to the same file,
I get a locking conflict (I'm not using ZEO here -- that's in the works,
but I want to reserve the right to use a plain vanilla
{File,Berkeley}Storage.)  So the setup is unexciting:

  from ZODB import DB
  from ZODB.FileStorage import FileStorage
  filename = "/tmp/mxdb.fs"
  file = FileStorage (filename)

Now open two connections to the same file:

  db1 = DB(file)
  conn1 = db1.open()
  root1 = conn1.root()

  db2 = DB(file)
  conn2 = db2.open()
  root2 = conn2.root()

Fetch the same object from each connection, and see what we have:

  me1 = root1['user_db'].users['gward']
  me2 = root2['user_db'].users['gward']

  print `me1`, `me1._p_oid`
  print `me2`, `me2._p_oid`

Output of this step:

  <User at 82401c0: gward> '\000\000\000\000\000\000\000!'
  <User at 824dfd8: gward> '\000\000\000\000\000\000\000!'

...ie. two in-memory "copies" of the same database object, which leads
me to believe I can update them independently.  Let's see:

  me1.prefix = "Sir"
  print me1.format_realname(include_prefix=1)
  print me2.format_realname(include_prefix=1)

And the output from this step is:

  Sir Greg Ward
  Greg Ward

Cool!  I think this is (part of) the behaviour I was looking for -- same
database object, different in-memory "facade" presented to the Python
code working on it.

The clue I'm missing is how to "unify" the two disparate versions: how
do I commit the changes to me1 so that me2 also becomes "Sir Greg Ward",
or alternately, how do I abort the changes to me1 so that this change is
never seen?

-----

So, is this possible?


Since I did my first post however, I changed my app quite a bit. I took the
StandaloneZODB distro, ZServer and ZPublisher and put them together, in a
way I took zope and changed it to publish my own modules instead. This way
it handles transactions for me, just like zope does. But, the objects that
I'm publishing are running threads that are changing the objects too. An
request coming from the web changing the object will do the commit
automatically, but how should I do it from the threads? If I have understood
things, I should open a new connection from the thread, cause
get_transaction is woking on a thread at a time, and then handle those
commits myself?


Hope anyone understands what I'm trying to say ;)

Thanks

/Magnus