[openstack-dev] [Neutron] DB: transaction isolation and related questions
Mike Bayer
mbayer at redhat.com
Wed Nov 19 20:27:44 UTC 2014
> On Nov 19, 2014, at 2:58 PM, Jay Pipes <jaypipes at gmail.com> wrote:
>
>
>> In other words, the retry logic like the following will not work:
>>
>> def allocate_obj():
>> with session.begin(subtrans=True):
>> for i in xrange(n_retries):
>> obj = session.query(Model).filter_by(filters)
>> count = session.query(Model).filter_by(id=obj.id
>> <http://obj.id>).update({'allocated': True})
>> if count:
>> return obj
>>
>> since usually methods like allocate_obj() is called from within another
>> transaction, we can't simply put transaction under 'for' loop to fix the
>> issue.
>
> Exactly. The above code, from here:
>
> https://github.com/openstack/neutron/blob/master/neutron/plugins/ml2/drivers/helpers.py#L98
>
> has no chance of working at all under the existing default isolation levels for either MySQL or PostgreSQL. If another session updates the same row in between the time the first session began and the UPDATE statement in the first session starts, then the first session will return 0 rows affected. It will continue to return 0 rows affected for each loop, as long as the same transaction/session is still in effect, which in the code above, is the case.
oh, because it stays a zero, right. yeah I didn’t understand that that was the failure case before. should have just pinged you on IRC to answer the question without me wasting everyone’s time! :)
>
> The design of the Neutron plugin code's interaction with the SQLAlchemy session object is the main problem here. Instead of doing all of this within a single transactional container, the code should instead be changed to perform the SELECT statements in separate transactions/sessions.
>
> That means not using the session parameter supplied to the neutron.plugins.ml2.drivers.helpers.TypeDriverHelper.allocate_partially_specified_segment() method, and instead performing the SQL statements in separate transactions.
>
> Mike Bayer's EngineFacade blueprint work should hopefully unclutter the current passing of a session object everywhere, but until that hits, it should be easy enough to simply ensure that you don't use the same session object over and over again, instead of changing the isolation level.
OK but EngineFacade was all about unifying broken-up transactions into one big transaction. I’ve never been partial to the “retry something inside of a transaction” approach i usually prefer to have the API method raise and retry it’s whole series of operations all over again. How do you propose EngineFacade’s transaction-unifying behavior with separate-transaction-per-SELECT (and wouldn’t that need to include the UPDATE as well? ) Did you see it as having the “one main transaction” with separate “ad-hoc, out of band” transactions as needed?
>
> All the best,
> -jay
>
>> Your feedback is appreciated.
>>
>> Thanks,
>> Eugene.
>>
>>
>>
>> _______________________________________________
>> OpenStack-dev mailing list
>> OpenStack-dev at lists.openstack.org
>> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
>>
>
> _______________________________________________
> OpenStack-dev mailing list
> OpenStack-dev at lists.openstack.org
> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
More information about the OpenStack-dev
mailing list