[openstack-dev] [oslo.db][nova] NovaObject.save() needs its own DB transaction

Jay Pipes jaypipes at gmail.com
Thu Nov 27 18:01:10 UTC 2014

On 11/19/2014 01:25 PM, Mike Bayer wrote:
> OK so here is why EngineFacade as described so far doesn’t work, because if it is like this:
> def some_api_operation ->
>          novaobject1.save() ->
>                 @writer
>                 def do_some_db_thing()
>          novaobject2.save() ->
>                 @writer
>                 def do_some_other_db_thing()
> then yes, those two @writer calls aren’t coordinated.   So yes, I think something that ultimately communicates the same meaning as @writer needs to be at the top:
> @something_that_invokes_writer_without_exposing_db_stuff
> def some_api_operation ->
>      # … etc
> If my decorator is not clear enough, let me clarify that a decorator that is present at the API/ nova objects layer will interact with the SQL layer through some form of dependency injection, and not any kind of explicit import; that is, when the SQL layer is invoked, it registers some kind of state onto the @something_that_invokes_writer_without_exposing_db_stuff system that causes its “cleanup”, in this case the commit(), to occur at the end of that topmost decorator.
>> I think the following pattern would solve it:
>> @remotable
>> def save():
>>     session = <insert magic here>
>>     try:
>>         r = self._save(session)
>>         session.commit() (or reader/writer magic from oslo.db)
>>         return r
>>     except Exception:
>>         session.rollback() (or reader/writer magic from oslo.db)
>>         raise
>> @definitelynotremotable
>> def _save(session):
>>     previous contents of save() move here
>>     session is explicitly passed to db api calls
>>     cascading saves call object._save(session)
> so again with EngineFacade rewrite, the @definitelynotremotable system should also interact such that if @writer is invoked internally, an error is raised, just the same as when @writer is invoked within @reader.

My impression after reading the EngineFacade spec (and the reason I 
supported it, and still support the idea behind it) was that the "API 
call" referred to in the EngineFacade spec was the *nova-conductor* API 
call, not the *nova-api* API call. We need a way to mark an RPC API call 
on the nova-conductor as involving a set of writer or reader DB calls, 
and that's what I thought we were referring to in that spec. I 
specifically did not think that we were leaving the domain of the 
nova-conductor, because clearly we would be leaving the domain of a 
single RPC call in that case, and in order to do transactional 
containers, we'd need to use two-phase commit, which is definitely not 
something I recommend...

So, in short, for the EngineFacade effort, I believe the @reader and 
@writer decorators should be on the conductor RPC API calls.


More information about the OpenStack-dev mailing list