<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">>In a multi-writer galera cluster both SELECT FOR UPDATE and CAS won't fail until commit time<div class=""><br class=""></div><div class="">Good point, I did not consider multi-writer. But anyway, my point was that opt.2 is no worse than opt.1.</div><div class=""><br class=""></div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 13 May 2016, at 12:04, Kevin Benton <<a href="mailto:kevin@benton.pub" class="">kevin@benton.pub</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">><span style="font-size:12.8px" class="">While opt.2 only prevents the conflicting changes, but does not guarantee that </span><span style="font-size:12.8px" class="">the object does not change while within the context,</span><div class=""><br class=""></div><div class="">I'm not sure what you mean here. In a multi-writer galera cluster both SELECT FOR UPDATE and CAS won't fail until commit time if someone writes to another server.</div><div class="">So the DB lock only provides the conflicting change guarantee in a single-writer mysql setup.</div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Thu, May 12, 2016 at 11:26 AM, Ilya Chukhnakov <span dir="ltr" class=""><<a href="mailto:ichukhnakov@mirantis.com" target="_blank" class="">ichukhnakov@mirantis.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi everyone.<br class="">
<br class="">
I’ve recently found that straightforward use of NeutronDbObject is prone to<br class="">
concurrency-related problems.<br class="">
<br class="">
I’ve submitted a patch set [3] with some tests to show that without special<br class="">
treatment using NeutronDbObject could lead to unexpected results.<br class="">
<br class="">
Further patch sets will provide acquire_object/acquire_objects contextmanager<br class="">
methods to the NeutronDbObject class. These methods are to be used in place of<br class="">
get_object/get_objects whenever the user intends to make changes to the object.<br class="">
These methods would start an autonested_transaction.<br class="">
<br class="">
There are (at least) two potential options for the implementation:<br class="">
<br class="">
1. Based on the DB locks (e.g. SELECT FOR UPDATE/SqlAlchemy with_for_update).<br class="">
<br class="">
   pros:<br class="">
     - the object is guaranteed to not be changed while within the context<br class="">
<br class="">
   cons:<br class="">
     - prone to deadlocks ([1] and potentially when locking multiple objects)<br class="">
<br class="">
2. Lock-free CAS based on object version counter. Can use SqlAlchemy version<br class="">
   counter [2] or add our own. If conflicting changes are detected upon exiting<br class="">
   the context (i.e. version counter held differs from the one in the DB), will<br class="">
   raise OSLO RetryRequest exception.<br class="">
<br class="">
   pros:<br class="">
     - does not require locking<br class="">
<br class="">
   cons:<br class="">
     - require an additional field in the models<br class="">
<br class="">
While opt.2 only prevents the conflicting changes, but does not guarantee that<br class="">
the object does not change while within the context, opt.1 may seem<br class="">
preferential. But even with opt.1 the user should not expect that the changes<br class="">
made to the object while within the context will get to the database as the<br class="">
autonested_transaction could fail on flush/commit.<br class="">
<br class="">
So I’d like to hear others’ opinion on the problem and which of the two<br class="">
implementation options would be preferred? Or maybe someone has a better idea.<br class="">
<br class="">
[1] <a href="https://wiki.openstack.org/wiki/OpenStack_and_SQLAlchemy#MySQLdb_.2B_eventlet_.3D_sad" rel="noreferrer" target="_blank" class="">https://wiki.openstack.org/wiki/OpenStack_and_SQLAlchemy#MySQLdb_.2B_eventlet_.3D_sad</a><br class="">
[2] <a href="http://docs.sqlalchemy.org/en/rel_0_9/orm/versioning.html" rel="noreferrer" target="_blank" class="">http://docs.sqlalchemy.org/en/rel_0_9/orm/versioning.html</a><br class="">
<br class="">
[3] <a href="https://review.openstack.org/#/c/315705/" rel="noreferrer" target="_blank" class="">https://review.openstack.org/#/c/315705/</a><br class="">
<br class="">
--<br class="">
Thanks,<br class="">
Ilya<br class="">
__________________________________________________________________________<br class="">
OpenStack Development Mailing List (not for usage questions)<br class="">
Unsubscribe: <a href="http://OpenStack-dev-request@lists.openstack.org/?subject:unsubscribe" rel="noreferrer" target="_blank" class="">OpenStack-dev-request@lists.openstack.org?subject:unsubscribe</a><br class="">
<a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" rel="noreferrer" target="_blank" class="">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br class="">
</blockquote></div><br class=""></div>
__________________________________________________________________________<br class="">OpenStack Development Mailing List (not for usage questions)<br class="">Unsubscribe: <a href="mailto:OpenStack-dev-request@lists.openstack.org" class="">OpenStack-dev-request@lists.openstack.org</a>?subject:unsubscribe<br class=""><a href="http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev" class="">http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev</a><br class=""></div></blockquote></div><br class=""></div></body></html>