Concurrency with AASM, Isolation Levels
I’ve posted two guest articles over on the Engine Yard blog this week on database related topics:
They’re in the same vein as what I’ve been posting here, so worth a read if you’ve been digging it.
The US tour kicks off this Saturday in San Francisco, and there’s still a couple of spots available. You can still register over at www.dbisyourfriend.com
“Your Database Is Your Friend” training sessions are happening throughout the US and UK in the coming months. One is likely coming to a city near you. For more information and free screencasts, head on over to www.dbisyourfriend.com
acts_as_state_machine is not concurrent
Here is a short 4 minute screencast in which I show you how the acts as state machine (AASM) gem fails in a concurrent environment, and also how to fix it.
(If embedding doesn’t work or the text is too small to read, you can grab a high resolution version direct from Vimeo)
It’s a pretty safe bet that you want to obtain a lock before all state transitions, so you can use a bit of method aliasing to do just that. This gives you much neater code than the quick fix I show in the screencast, just make sure you understand what it is doing!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
class ActiveRecord::Base def self.obtain_lock_before_transitions AASM::StateMachine[self].events.keys.each do |t| define_method("#{t}_with_lock!") do transaction do lock! send("#{t}_without_lock!") end end alias_method_chain "#{t}!", :lock end end end class Tractor # ... aasm_event :buy do transitions :to => :bought, :from => [:for_sale] end obtain_lock_before_transitions end |
This is a small taste of my DB is your friend training course, that helps you build solid rails applications by finding the sweet spot between stored procedures and treating your database as a hash. July through September I am running full day sessions in the US and UK. Chances are I’m coming to your city. Check it out at http://www.dbisyourfriend.com