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:
parent
c5b8791e3f
commit
8200014062
@ -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:
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user