Note that there are some explanatory texts on larger screens.

plurals
  1. POsolving for a race condition in rails ( limited number of X in Y )
    text
    copied!<p>Edit: Using MySQL...</p> <p>Say you have an app that adds students to a class, and that class has limited space... so you do something like this:</p> <pre><code>def add if some_classroom.size &lt; MAX_SIZE add_student_to_class end end </code></pre> <p>That's a race condition in a multi-threaded environment. Lame.</p> <p>Assuming we </p> <ol> <li>don't want this, and </li> <li>don't want to lock our classroom table or record (which causes our app to suck elsewhere)</li> </ol> <p>What do we do?</p> <p>I propose this:</p> <pre><code>class Classroom &lt; ActiveRecord::Base has_one :classroom_lock after_create :create_lock_record def create_lock_record c = ClassroomLock.new c.classroom = self c.save! end end class ClassroomLock &lt; ActiveRecord::Base belongs_to :classroom end def add c = Classroom.first ActiveRecord::Base.transaction do c.classroom_lock.lock! c = Classroom.first #load this again (it might have changed) if c.size &lt; MAX_SIZE c.add_new_student(some_student) else do_stuff_about_not_enough_room end end end </code></pre> <p>This seems like it should work awesomely. My (ficticious) Classroom#show method doesn't block because the classroom record isn't actually locked and the add method is effectively single threaded since any additional processes will be forced to wait at the lock! line until the lock is released.</p> <p>Does this work? Maybe? I think so? I don't know...</p> <p>I've done a fair bit of hammering this with multiple processes at once, but it's hard to know for sure (it is a race condition after all).</p> <p>Can anyone provide some additional insight?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload