Collabortation Diagrams

Caution

This document hasn’t been reviewed since 2005 and is likely out of date.

This file contains several collaboration diagrams for the ZODB.

Simple fetch, modify, commit

Participants

  • DB: ZODB.DB.DB

  • C: ZODB.Connection.Connection

  • S: ZODB.FileStorage.FileStorage

  • T: transaction.interfaces.ITransaction

  • TM: transaction.interfaces.ITransactionManager

  • o1, o2, ...: pre-existing persistent objects

Scenario

DB.open()
 create C
 TM.registerSynch(C)
TM.begin()
 create T
C.get(1) # fetches o1
C.get(2) # fetches o2
C.get(3) # fetches o3
o1.modify() # anything that modifies o1
 C.register(o1)
 T.join(C)
o2.modify()
 C.register(o2)
 # T.join(C) does not happen again
o1.modify()
 # C.register(o1) doesn't happen again, because o1 was already
 # in the changed state.
T.commit()
 C.beforeCompletion(T)
 C.tpc_begin(T)
 S.tpc_begin(T)
 C.commit(T)
 S.store(1, ..., T)
 S.store(2, ..., T)
 # o3 is not stored, because it wasn't modified
 C.tpc_vote(T)
 S.tpc_vote(T)
 C.tpc_finish(T)
 S.tpc_finish(T, f) # f is a callback function, which arranges
 # to call DB.invalidate (next)
 DB.invalidate(tid, {1: 1, 2: 1}, C)
 C2.invalidate(tid, {1: 1, 2: 1}) # for all connections
 # C2 to DB, where C2
 # is not C
 TM.free(T)
 C.afterCompletion(T)
 C._flush_invalidations()
 # Processes invalidations that may have come in from other
 # transactions.

Simple fetch, modify, abort

Participants

  • DB: ZODB.DB.DB

  • C: ZODB.Connection.Connection

  • S: ZODB.FileStorage.FileStorage

  • T: transaction.interfaces.ITransaction

  • TM: transaction.interfaces.ITransactionManager

  • o1, o2, ...: pre-existing persistent objects

Scenario

DB.open()
 create C
 TM.registerSynch(C)
TM.begin()
 create T
C.get(1) # fetches o1
C.get(2) # fetches o2
C.get(3) # fetches o3
o1.modify() # anything that modifies o1
 C.register(o1)
 T.join(C)
o2.modify()
 C.register(o2)
 # T.join(C) does not happen again
o1.modify()
 # C.register(o1) doesn't happen again, because o1 was already
 # in the changed state.
T.abort()
 C.beforeCompletion(T)
 C.abort(T)
 C._cache.invalidate(1) # toss changes to o1
 C._cache.invalidate(2) # toss changes to o2
 # o3 wasn't modified, and its cache entry isn't invalidated.
 TM.free(T)
 C.afterCompletion(T)
 C._flush_invalidations()
 # Processes invalidations that may have come in from other
 # transactions.

Rollback of a savepoint

Participants

  • T: transaction.interfaces.ITransaction

  • o1, o2, o3: some persistent objects

  • C1, C2, C3: resource managers

  • S1, S2: Transaction savepoint objects

  • s11, s21, s22: resource-manager savepoints

Scenario

create T
o1.modify()
 C1.regisiter(o1)
 T.join(C1)
T.savepoint()
 C1.savepoint()
 return s11
 return S1 = Savepoint(T, [r11])
o1.modify()
 C1.regisiter(o1)
o2.modify()
 C2.regisiter(o2)
 T.join(C2)
T.savepoint()
 C1.savepoint()
 return s21
 C2.savepoint()
 return s22
 return S2 = Savepoint(T, [r21, r22])
o3.modify()
 C3.regisiter(o3)
 T.join(C3)
S1.rollback()
 S2.rollback()
 T.discard()
 C1.discard()
 C2.discard()
 C3.discard()
 o3.invalidate()
 S2.discard()
 s21.discard() # roll back changes since previous, which is r11
 C1.discard(s21)
 o1.invalidate()
 # truncates temporary storage to s21's position
 s22.discard() # roll back changes since previous, which is r11
 C1.discard(s22)
 o2.invalidate()
 # truncates temporary storage to beginning, because
 # s22 was the first savepoint. (Perhaps conection
 # savepoints record the log position before the
 # data were written, which is 0 in this case.
T.commit()
 C1.beforeCompletion(T)
 C2.beforeCompletion(T)
 C3.beforeCompletion(T)
 C1.tpc_begin(T)
 S1.tpc_begin(T)
 C2.tpc_begin(T)
 C3.tpc_begin(T)
 C1.commit(T)
 S1.store(1, ..., T)
 C2.commit(T)
 C3.commit(T)
 C1.tpc_vote(T)
 S1.tpc_vote(T)
 C2.tpc_vote(T)
 C3.tpc_vote(T)
 C1.tpc_finish(T)
 S1.tpc_finish(T, f) # f is a callback function, which arranges
 c# to call DB.invalidate (next)
 DB.invalidate(tid, {1: 1}, C)
 TM.free(T)
 C1.afterCompletion(T)
 C1._flush_invalidations()
 C2.afterCompletion(T)
 C2._flush_invalidations()
 C3.afterCompletion(T)
 C3._flush_invalidations()