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()