diff --git a/doc/source/contributor/effective_neutron.rst b/doc/source/contributor/effective_neutron.rst index c7e91e08d06..b2a4f56c638 100644 --- a/doc/source/contributor/effective_neutron.rst +++ b/doc/source/contributor/effective_neutron.rst @@ -140,43 +140,6 @@ Document common pitfalls as well as good practices done during database developm `patch 257086 `_ which changed the 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 inserted primary keys not the last inserted primary key: diff --git a/doc/source/contributor/internals/retries.rst b/doc/source/contributor/internals/retries.rst index 64342a33ad0..8aa08b1ff2d 100644 --- a/doc/source/contributor/internals/retries.rst +++ b/doc/source/contributor/internals/retries.rst @@ -81,11 +81,13 @@ something like this: :: + from neutron.db import api as db_api + def create_port(context, ip_address, mac_address): _ensure_mac_not_in_use(context, mac_address) _ensure_ip_not_in_use(context, ip_address) try: - with context.session.begin(): + with db_api.CONTEXT_READER.using(context): port_obj = Port(ip=ip_address, mac=mac_address) do_expensive_thing(...) do_extra_other_thing(...) @@ -124,7 +126,7 @@ code cleaner. def create_port(context, ip_address, mac_address): _ensure_mac_not_in_use(context, mac_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) do_expensive_thing(...) do_extra_other_thing(...) @@ -163,7 +165,7 @@ Here are some usage examples: @db_api.retry_if_session_inactive() def atomic_bulk_create_elephants(context, elephants): - with context.session.begin(): + with db_api.CONTEXT_WRITER.using(context): for elephant in elephants: # note that if create_elephant throws a retriable # exception, the decorator around it will not retry