======================= Collabortation Diagrams ======================= 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()