<div style="white-space:pre-wrap">Locking can be tricky,<br><br>MySQL's auto increment should be avoided for your purpose because it happens outside a transaction ( if you rollback a transaction the table auto increment doesn't go back to what it was)<br><br>I'm not sure what deadlocking issues you're having, but this could work, however non-concurrently per parent:<br><br>parent.with_lock do<br> Child.create!(idx: parent.child_idx + 1)<br> parent.child_idx += 1<br> parent.save!<br>end<br><br>If you're getting deadlocks because too much stuff is happening inside the lock, you could seperate the create into a create and then update with more processed information, as the update doesn't need the lock on the parent. <br><br>Eaden <br><br>@eadz <br><br></div><br><div class="gmail_quote"><div dir="ltr">On Fri, 2 Sep 2016 at 11:34 AM, Andrew Stewart <<a href="mailto:boss@airbladesoftware.com">boss@airbladesoftware.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">> If it’s just the index of the child within the ordered collection of children then I’d expect that to be fine.<br>
<br>
Yes, that's what it is.<br>
<br>
> The locking behaviour depends on what autoincrement lock mode you’re using, but hopefully that is already working.<br>
<br>
My current (lock-y) implementation doesn't use MySQL's autoincrement feature. It's simply an integer column in the parent which is incremented in the child's after_create callback, which will be part of the same transaction.<br>
<br>
class Parent < ActiveRecord::Base<br>
has_many :children<br>
<br>
def next_child_number<br>
increment! :child_number<br>
child_number<br>
end<br>
end<br>
<br>
class Child < ActiveRecord::Base<br>
belongs_to :parent<br>
<br>
after_create :set_number<br>
<br>
def set_number<br>
n = parent.next_child_number<br>
update_column :friendly_id, "#{other_stuff}-#{n}"<br>
update_column :number, n<br>
end<br>
end<br>
<br>
> Your subsequent email suggests that you want to actually store this value against the child rather than derive it, which isn’t quite what I meant, but it should be doable. Once the autoincremented ID has been assigned, the child index is fixed (i.e. you can safely assign it with an UPDATE whenever is convenient) as long as you don’t allow previous children to be deleted.<br>
<br>
Which begs the original question: how to derive the child index safely?<br>
<br>
(As far as I can remember from 8 years ago, I implemented it the way I did because it seemed more efficient to just keep an index counter on the parent than to query the child table each time. Although I don't understand yet why I'm getting occasional deadlocks / uniqueness violations, I assume it's because of the involvement of the parent table.)<br>
_______________________________________________<br>
Chat mailing list<br>
<a href="mailto:Chat@lists.lrug.org" target="_blank">Chat@lists.lrug.org</a><br>
Archives: <a href="http://lists.lrug.org/pipermail/chat-lrug.org" rel="noreferrer" target="_blank">http://lists.lrug.org/pipermail/chat-lrug.org</a><br>
Manage your subscription: <a href="http://lists.lrug.org/options.cgi/chat-lrug.org" rel="noreferrer" target="_blank">http://lists.lrug.org/options.cgi/chat-lrug.org</a><br>
List info: <a href="http://lists.lrug.org/listinfo.cgi/chat-lrug.org" rel="noreferrer" target="_blank">http://lists.lrug.org/listinfo.cgi/chat-lrug.org</a><br>
</blockquote></div>