Represent a 'nested', or SAVEPOINT transaction. The :class:`.NestedTransaction` object is created by calling the :meth:`_engine.Connection.begin_nested` method of :class:`_engine.Connection`. When using :class:`.NestedTransaction`, the semantics of "begin" / "commit" / "rollbac
| 2736 | |
| 2737 | |
| 2738 | class NestedTransaction(Transaction): |
| 2739 | """Represent a 'nested', or SAVEPOINT transaction. |
| 2740 | |
| 2741 | The :class:`.NestedTransaction` object is created by calling the |
| 2742 | :meth:`_engine.Connection.begin_nested` method of |
| 2743 | :class:`_engine.Connection`. |
| 2744 | |
| 2745 | When using :class:`.NestedTransaction`, the semantics of "begin" / |
| 2746 | "commit" / "rollback" are as follows: |
| 2747 | |
| 2748 | * the "begin" operation corresponds to the "BEGIN SAVEPOINT" command, where |
| 2749 | the savepoint is given an explicit name that is part of the state |
| 2750 | of this object. |
| 2751 | |
| 2752 | * The :meth:`.NestedTransaction.commit` method corresponds to a |
| 2753 | "RELEASE SAVEPOINT" operation, using the savepoint identifier associated |
| 2754 | with this :class:`.NestedTransaction`. |
| 2755 | |
| 2756 | * The :meth:`.NestedTransaction.rollback` method corresponds to a |
| 2757 | "ROLLBACK TO SAVEPOINT" operation, using the savepoint identifier |
| 2758 | associated with this :class:`.NestedTransaction`. |
| 2759 | |
| 2760 | The rationale for mimicking the semantics of an outer transaction in |
| 2761 | terms of savepoints so that code may deal with a "savepoint" transaction |
| 2762 | and an "outer" transaction in an agnostic way. |
| 2763 | |
| 2764 | .. seealso:: |
| 2765 | |
| 2766 | :ref:`session_begin_nested` - ORM version of the SAVEPOINT API. |
| 2767 | |
| 2768 | """ |
| 2769 | |
| 2770 | __slots__ = ("connection", "is_active", "_savepoint", "_previous_nested") |
| 2771 | |
| 2772 | _savepoint: str |
| 2773 | |
| 2774 | def __init__(self, connection: Connection): |
| 2775 | assert connection._transaction is not None |
| 2776 | if connection._trans_context_manager: |
| 2777 | TransactionalContext._trans_ctx_check(connection) |
| 2778 | self.connection = connection |
| 2779 | self._savepoint = self.connection._savepoint_impl() |
| 2780 | self.is_active = True |
| 2781 | self._previous_nested = connection._nested_transaction |
| 2782 | connection._nested_transaction = self |
| 2783 | |
| 2784 | def _deactivate_from_connection(self, warn: bool = True) -> None: |
| 2785 | if self.connection._nested_transaction is self: |
| 2786 | self.connection._nested_transaction = self._previous_nested |
| 2787 | elif warn: |
| 2788 | util.warn( |
| 2789 | "nested transaction already deassociated from connection" |
| 2790 | ) |
| 2791 | |
| 2792 | @property |
| 2793 | def _deactivated_from_connection(self) -> bool: |
| 2794 | return self.connection._nested_transaction is not self |
| 2795 |