編集:MySQLを使用して...レールで競合状態のために(YでXの制限数)を解く
あなたはクラスに生徒を追加するアプリがあると、そのクラスには、限られたスペースを持っています...したがって、次のようなことを行います。
def add
if some_classroom.size < MAX_SIZE
add_student_to_class
end
end
これは、マルチスレッド環境での競合状態です。ラメ。我々
- はこれをしたくない、と
- は何
(我々のアプリは、他の場所で吸うの原因となる)私たちの教室のテーブルやレコードをロックしたくないと仮定すると、
私たちはしますか?
私はこれを提案している:それは上空で動作するはずのよう
class Classroom < 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 < 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 < MAX_SIZE
c.add_new_student(some_student)
else
do_stuff_about_not_enough_room
end
end
end
これがそうです。私の(架空の)Classroom#showメソッドは、教室の記録が実際にはロックされておらず、addメソッドが効果的にシングルスレッドであるためブロックされません。ロックが解除されるまで
これは機能しますか?多分?私はそう思う?私は知らない...
これを複数のプロセスで同時に処理するのはかなり面倒ですが、結局のところ競合状態です。
誰でも追加の洞察を提供できますか?
あなたはどのようなデータベースを使用していますか? – meagar
私はmysqlを使用しています – jsharpe
'LOCK IN SHARE MODE'を使用してください。手巻きのソリューションを投げ捨て、http://guides.rubyonrails.org/active_record_querying.html#pessimistic-locking – meagar