Remove documentation about nested transactions

With the new engine facade in place, a context session can execute
one single transaction at once. Nested transactions are no longer
supported.

This patch also changes db related examples in the "retries" document
that they uses engine facade.

Partially-Implements blueprint: enginefacade-switch

Change-Id: I978a24c3b30c2bb0a3ea6aa25ebf91ca5c58b8c9
Co-authored-by: Slawek Kaplonski <skaplons@redhat.com>
This commit is contained in:
Rodolfo Alonso Hernandez 2021-01-14 15:44:55 +00:00 committed by Slawek Kaplonski
parent c5b8791e3f
commit 8200014062
2 changed files with 5 additions and 40 deletions

View File

@ -140,43 +140,6 @@ Document common pitfalls as well as good practices done during database developm
`patch 257086 <https://review.opendev.org/#/c/257086/>`_ which changed the `patch 257086 <https://review.opendev.org/#/c/257086/>`_ which changed the
availability zone code from the incorrect style to a database friendly one. availability zone code from the incorrect style to a database friendly one.
* Sometimes in code we use the following structures:
.. code:: python
def create():
with context.session.begin(subtransactions=True):
create_something()
try:
_do_other_thing_with_created_object()
except Exception:
with excutils.save_and_reraise_exception():
delete_something()
def _do_other_thing_with_created_object():
with context.session.begin(subtransactions=True):
....
The problem is that when exception is raised in ``_do_other_thing_with_created_object``
it is caught in except block, but the object cannot be deleted in except
section because internal transaction from ``_do_other_thing_with_created_object``
has been rolled back. To avoid this nested transactions should be used.
For such cases help function ``safe_creation`` has been created in
``neutron/db/_utils.py``.
So, the example above should be replaced with:
.. code:: python
_safe_creation(context, create_something, delete_something,
_do_other_thing_with_created_object)
Where nested transaction is used in _do_other_thing_with_created_object
function.
The ``_safe_creation function can also be passed the ``transaction=False``
argument to prevent any transaction from being created just to leverage
the automatic deletion on exception logic.
* Beware of ResultProxy.inserted_primary_key which returns a list of last * Beware of ResultProxy.inserted_primary_key which returns a list of last
inserted primary keys not the last inserted primary key: inserted primary keys not the last inserted primary key:

View File

@ -81,11 +81,13 @@ something like this:
:: ::
from neutron.db import api as db_api
def create_port(context, ip_address, mac_address): def create_port(context, ip_address, mac_address):
_ensure_mac_not_in_use(context, mac_address) _ensure_mac_not_in_use(context, mac_address)
_ensure_ip_not_in_use(context, ip_address) _ensure_ip_not_in_use(context, ip_address)
try: try:
with context.session.begin(): with db_api.CONTEXT_READER.using(context):
port_obj = Port(ip=ip_address, mac=mac_address) port_obj = Port(ip=ip_address, mac=mac_address)
do_expensive_thing(...) do_expensive_thing(...)
do_extra_other_thing(...) do_extra_other_thing(...)
@ -124,7 +126,7 @@ code cleaner.
def create_port(context, ip_address, mac_address): def create_port(context, ip_address, mac_address):
_ensure_mac_not_in_use(context, mac_address) _ensure_mac_not_in_use(context, mac_address)
_ensure_ip_not_in_use(context, ip_address) _ensure_ip_not_in_use(context, ip_address)
with context.session.begin(): with db_api.CONTEXT_READER.using(context):
port_obj = Port(ip=ip_address, mac=mac_address) port_obj = Port(ip=ip_address, mac=mac_address)
do_expensive_thing(...) do_expensive_thing(...)
do_extra_other_thing(...) do_extra_other_thing(...)
@ -163,7 +165,7 @@ Here are some usage examples:
@db_api.retry_if_session_inactive() @db_api.retry_if_session_inactive()
def atomic_bulk_create_elephants(context, elephants): def atomic_bulk_create_elephants(context, elephants):
with context.session.begin(): with db_api.CONTEXT_WRITER.using(context):
for elephant in elephants: for elephant in elephants:
# note that if create_elephant throws a retriable # note that if create_elephant throws a retriable
# exception, the decorator around it will not retry # exception, the decorator around it will not retry