> On Nov 19, 2014, at 2:58 PM, Jay Pipes <[email protected]> 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 >> [email protected] >> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev >> > > _______________________________________________ > OpenStack-dev mailing list > [email protected] > http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev _______________________________________________ OpenStack-dev mailing list [email protected] http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
