Example #1
0
    def _begin(self, transaction):
        # This function is called when PJDataManager joins transaction. When
        # two phase commit is requested, we will assign transaction id to
        # underlying connection.
        if not PJ_TWO_PHASE_COMMIT_ENABLED:
            # We don't need to do anything special when two phase commit is
            # disabled. Transaction starts automatically.
            return

        assert self._pristine, ("Error attempting to add data manager "
                                "from old transaction. Create a new "
                                "PJDataManager for new transaction, do not "
                                "modify objects from previously committed "
                                "transactions")
        self._pristine = False

        # Create a global id for the transaction. If it wasn't yet created,
        # create now.
        try:
            txnid = transaction.data(PREPARED_TRANSACTION_ID)
        except KeyError:
            txnid = str(uuid.uuid4())
            transaction.set_data(PREPARED_TRANSACTION_ID, txnid)

        try:
            xid = self._conn.xid(0, txnid, self.database)
            self._conn.tpc_begin(xid)
        except psycopg2.Error as e:
            check_for_disconnect(e, 'PJDataManager._begin')
            raise
        self._tpc_activated = True
Example #2
0
    def commit(self, transaction):
        """Commit changes to an object"""

        transaction = transaction.data(self)

        if self._savepoint_storage is not None:

            # We first checkpoint the current changes to the savepoint
            self.savepoint()

            # then commit all of the savepoint changes at once
            self._commit_savepoint(transaction)

            # No need to call _commit since savepoint did.

        else:
            self._commit(transaction)

        for oid, serial in six.iteritems(self._readCurrent):
            try:
                self._storage.checkCurrentSerialInTransaction(
                    oid, serial, transaction)
            except ConflictError:
                self._cache.invalidate(oid)
                raise
Example #3
0
    def commit(self, transaction):
        """Commit changes to an object"""

        transaction = transaction.data(self)

        if self._savepoint_storage is not None:

            # We first checkpoint the current changes to the savepoint
            self.savepoint()

            # then commit all of the savepoint changes at once
            self._commit_savepoint(transaction)

            # No need to call _commit since savepoint did.

        else:
            self._commit(transaction)

        for oid, serial in six.iteritems(self._readCurrent):
            try:
                self._storage.checkCurrentSerialInTransaction(
                    oid, serial, transaction)
            except ConflictError:
                self._cache.invalidate(oid)
                raise
Example #4
0
    def _begin(self, transaction):
        # This function is called when PJDataManager joins transaction. When
        # two phase commit is requested, we will assign transaction id to
        # underlying connection.
        if not PJ_TWO_PHASE_COMMIT_ENABLED:
            # We don't need to do anything special when two phase commit is
            # disabled. Transaction starts automatically.
            return

        assert self._pristine, ("Error attempting to add data manager "
                                "from old transaction. Create a new "
                                "PJDataManager for new transaction, do not "
                                "modify objects from previously committed "
                                "transactions")
        self._pristine = False

        # Create a global id for the transaction. If it wasn't yet created,
        # create now.
        try:
            txnid = transaction.data(PREPARED_TRANSACTION_ID)
        except KeyError:
            txnid = str(uuid.uuid4())
            transaction.set_data(PREPARED_TRANSACTION_ID, txnid)

        try:
            xid = self._conn.xid(0, txnid, self.database)
            self._conn.tpc_begin(xid)
        except psycopg2.Error as e:
            check_for_disconnect(e, 'PJDataManager._begin')
            raise
        self._tpc_activated = True
Example #5
0
    def tpc_finish(self, transaction):
        """Indicate confirmation that the transaction is done.
        """
        transaction = transaction.data(self)

        serial = self._storage.tpc_finish(transaction)
        assert type(serial) is bytes, repr(serial)
        for oid_iterator in self._modified, self._creating:
            for oid in oid_iterator:
                obj = self._cache.get(oid)
                # Ignore missing objects and don't update ghosts.
                if obj is not None and obj._p_changed is not None:
                    obj._p_changed = 0
                    obj._p_serial = serial
        self._tpc_cleanup()
Example #6
0
    def tpc_finish(self, transaction):
        """Indicate confirmation that the transaction is done.
        """
        transaction = transaction.data(self)

        serial = self._storage.tpc_finish(transaction)
        assert type(serial) is bytes, repr(serial)
        for oid_iterator in self._modified, self._creating:
            for oid in oid_iterator:
                obj = self._cache.get(oid)
                # Ignore missing objects and don't update ghosts.
                if obj is not None and obj._p_changed is not None:
                    obj._p_changed = 0
                    obj._p_serial = serial
        self._tpc_cleanup()
Example #7
0
    def tpc_vote(self, transaction):
        """Verify that a data manager can commit the transaction."""
        try:
            vote = self._storage.tpc_vote
        except AttributeError:
            return

        transaction = transaction.data(self)

        try:
            s = vote(transaction)
        except ReadConflictError as v:
            if v.oid:
                self._cache.invalidate(v.oid)
            raise
        if s:
            # Resolved conflicts.
            for oid in s:
                obj = self._cache.get(oid)
                if obj is not None:
                    del obj._p_changed  # transition from changed to ghost
Example #8
0
    def tpc_vote(self, transaction):
        """Verify that a data manager can commit the transaction."""
        try:
            vote = self._storage.tpc_vote
        except AttributeError:
            return

        transaction = transaction.data(self)

        try:
            s = vote(transaction)
        except ReadConflictError as v:
            if v.oid:
                self._cache.invalidate(v.oid)
            raise
        if s:
            # Resolved conflicts.
            for oid in s:
                obj = self._cache.get(oid)
                if obj is not None:
                    del obj._p_changed # transition from changed to ghost
Example #9
0
    def tpc_abort(self, transaction):
        transaction = transaction.data(self)

        if self._import:
            self._import = None

        if self._savepoint_storage is not None:
            self._abort_savepoint()

        self._storage.tpc_abort(transaction)

        # Note: If we invalidate a non-ghostifiable object (i.e. a
        # persistent class), the object will immediately reread its
        # state.  That means that the following call could result in a
        # call to self.setstate, which, of course, must succeed.  In
        # general, it would be better if the read could be delayed
        # until the start of the next transaction.  If we read at the
        # end of a transaction and if the object was invalidated
        # during this transaction, then we'll read non-current data,
        # which we'll discard later in transaction finalization.  We
        # could, theoretically queue this invalidation by calling
        # self.invalidate.  Unfortunately, attempts to make that
        # change resulted in mysterious test failures.  It's pretty
        # unlikely that the object we are invalidating was invalidated
        # by another thread, so the risk of a reread is pretty low.
        # It's really not worth the effort to pursue this.

        self._cache.invalidate(self._modified)
        self._invalidate_creating()
        while self._added:
            oid, obj = self._added.popitem()
            if obj._p_changed:
                obj._p_changed = False
            del obj._p_oid
            del obj._p_jar
        self._tpc_cleanup()
Example #10
0
    def tpc_abort(self, transaction):
        transaction = transaction.data(self)

        if self._import:
            self._import = None

        if self._savepoint_storage is not None:
            self._abort_savepoint()

        self._storage.tpc_abort(transaction)

        # Note: If we invalidate a non-ghostifiable object (i.e. a
        # persistent class), the object will immediately reread its
        # state.  That means that the following call could result in a
        # call to self.setstate, which, of course, must succeed.  In
        # general, it would be better if the read could be delayed
        # until the start of the next transaction.  If we read at the
        # end of a transaction and if the object was invalidated
        # during this transaction, then we'll read non-current data,
        # which we'll discard later in transaction finalization.  We
        # could, theoretically queue this invalidation by calling
        # self.invalidate.  Unfortunately, attempts to make that
        # change resulted in mysterious test failures.  It's pretty
        # unlikely that the object we are invalidating was invalidated
        # by another thread, so the risk of a reread is pretty low.
        # It's really not worth the effort to pursue this.

        self._cache.invalidate(self._modified)
        self._invalidate_creating()
        while self._added:
            oid, obj = self._added.popitem()
            if obj._p_changed:
                obj._p_changed = False
            del obj._p_oid
            del obj._p_jar
        self._tpc_cleanup()
Example #11
0
 def tpc_abort(self, transaction):
     try:
         transaction = transaction.data(self)
         self._storage.tpc_abort(transaction)
     finally:
         self.close()
Example #12
0
 def tpc_vote(self, transaction):
     transaction = transaction.data(self)
     self._storage.tpc_vote(transaction)
Example #13
0
 def tpc_finish(self, transaction):
     transaction = transaction.data(self)
     self._storage.tpc_finish(transaction)
Example #14
0
File: DB.py Project: nolan57/ZODB
 def tpc_finish(self, transaction):
     transaction = transaction.data(self)
     self._storage.tpc_finish(transaction)
Example #15
0
 def commit(self, transaction):
     transaction = transaction.data(self)
     for tid in self._tids:
         self._storage.undo(tid, transaction)
Example #16
0
 def tpc_vote(self, transaction):
     transaction = transaction.data(self)
     self._storage.tpc_vote(transaction)
Example #17
0
File: DB.py Project: nolan57/ZODB
 def tpc_abort(self, transaction):
     transaction = transaction.data(self)
     self._storage.tpc_abort(transaction)
Example #18
0
 def tpc_abort(self, transaction):
     transaction = transaction.data(self)
     self._storage.tpc_abort(transaction)
Example #19
0
 def commit(self, transaction):
     transaction = transaction.data(self)
     for tid in self._tids:
         self._storage.undo(tid, transaction)