[ZODB-Dev] [ZODB4] - Shouldn't the new object be added to Connection._created ?

Jeremy Hylton jeremy@alum.mit.edu
Mon, 29 Jul 2002 14:27:53 -0400


Ury,

I tried your example code today with the current ZODB4 version in CVS,
and it worked.  I suspect this was just a bug; perhaps the same one
that Neil reported last week about modifications to ghosts being lost.

With current CVS, the print statement in the except clause prints 0 or
UPTODATE.  (Note that you can now get named constants from
Persistence.cPersistence.)

I needed to do some surgery to get ZEO working with current CVS, and I
needed to modify your script a little, too.  The imports have changed
around in CVS.  One recent change is that the transaction manager
doesn't implicitly abort a transaction on ConflictError, so the
get_transaction().abort() call is now important.

I'll checkin the ZEO changes on a branch, if you want
to have a try.  I'll also checkin a document summarizing the key
changes in current CVS.

Jeremy

PS Here's the version of the code that worked for me:

from ZODB import FileStorage
from ZODB.DB import DB
import Persistence
from Persistence.BTrees.IOBTree import IOBTree

from Transaction import get_transaction
from Transaction.Exceptions import ConflictError
from ZEO import ClientStorage

treename = 'aaaa'

class C(Persistence.Persistent):
    pass

def gen_conflict(db):
    conn = db.open()
    dbroot = conn.root()
    container = dbroot[treename]
    c = C()
    container[1] = c
    get_transaction().commit()
    c._p_deactivate()

def do_main():
    if 1:
        storage = ClientStorage.ClientStorage(('', 4500))
    else:
        storage = FileStorage.FileStorage('tst.fs')
    db = DB(storage)
    conn = db.open()
    dbroot = conn.root()

    if 1 : #not dbroot.has_key(treename):
        dbroot[treename]=IOBTree()
        get_transaction().commit()

    container = dbroot[treename]

    # make our container out-of-sync
    gen_conflict(db)

    c = C()
    try:
        container[1] = c
        get_transaction().commit()
    except ConflictError:
        print c._p_state   # 3 == ghost?
        get_transaction().abort()
        c.something = 1  # if I uncomment this line it dies here
        container[2] = c
        get_transaction().commit()

    db.close()
    storage.close()

if __name__=='__main__':
    do_main()