Commit bb618ce1 authored by Kirill Smelkov's avatar Kirill Smelkov

go/zodb: Prevent newly-created not-yet committed objects to go to ghost on deactivate

When object is just created, it is not yet assigned an OID, but can be
reachable from other objects. The code that processes transaction can
reach to that new object and try to PActivate/PDeactivate it. And
currently PDeactivate will drop the object state completely.

Another example of object without an OID is Bucket embedded into a Tree
object. There, the code that scans the tree can reach to that bucket and
try to activate/deactivate it, leading, again, to dropping state of that bucket.

-> Fix it.
parent 67f0d2cd
......@@ -261,6 +261,9 @@ func (obj *Persistent) PDeactivate() {
if obj.state >= CHANGED {
return
}
if obj.oid == InvalidOid { // newly created not-yet committed object
return
}
// TODO try to keep some pool of object in live state so that there is
// no constant load/unload on object access. XXX -> MRU cache?
......
......@@ -621,6 +621,18 @@ func testPersistentDB(t0 *testing.T, rawcache bool) {
t.checkObj(obj2, 102, at2, UPTODATE, 0, "kitty")
// newly created object should not go to ghost on deactivate
obj3 := NewMyObject(t.conn)
obj3.value = "new"
checkObj(t0, obj3, t.conn, InvalidOid, InvalidTid, UPTODATE, 0)
assert.Equal(obj3.value, "new")
t.PActivate(obj3)
checkObj(t0, obj3, t.conn, InvalidOid, InvalidTid, UPTODATE, 1)
obj3.PDeactivate()
checkObj(t0, obj3, t.conn, InvalidOid, InvalidTid, UPTODATE, 0)
assert.Equal(obj3.value, "new")
// finish tnx3 and txn2 - conn1 and conn2 go back to db pool
t.Abort()
t2.Abort()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment