Jonas Amundsen
2012-Dec-23 21:33 UTC
Isolation level for transactions initiated by ActiveRecord::Base#save
Hi, I am currently developing a website for selling tickets for events. A big issue here is concurrency. Multiple user should not be able to buy tickets at the exact same time and create a inconsistent database where more tickets have been sold than what was actually available. The act of purchasing is a two step process: 1. Check that there are enough available tickets left. 2. Create ticket records representing the users tickets. This is a critical part of the system and mutual exclusion must occur. At the moment, I have created a file based semaphore. Here is an isolated example of how I do this. The example shows mutual exclusion on a per-event basis, enabling multiple purchases to occur at the same time, as long as they are for seperate events. https://gist.github.com/4366276 This works swimmingly. (And it''s so cool!) But I would much rather like to utilize database transactions with an isolation level of serializable. I understand that ActiveRecord::Base#save already [creates a transaction](https://github.com/rails/rails/blob/master/activerecord/lib/active_record/transactions.rb#L257). To my knowledge, there''s nothing in Rails resembling the possibility to set the isolation level of an transaction. I think that is an issue. Isolation level is, in my opinion, a huge part of what transactions are. At least I could use a feature like that, in my case. It would be so awesome if one for instance could do transaction.save :isolation => :serializable or transaction :isolation => :serializable do> # … > endWhat do you think? -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-core/-/5WfQkkKQWvsJ. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Rafael Mendonça França
2012-Dec-23 23:08 UTC
Re: Isolation level for transactions initiated by ActiveRecord::Base#save
It is already implemented and will be shipped with Rails 4. See https://github.com/rails/rails/commit/392eeecc11a291e406db927a18b75f41b2658253 Rafael Mendonça França http://twitter.com/rafaelfranca https://github.com/rafaelfranca On Sun, Dec 23, 2012 at 6:33 PM, Jonas Amundsen <jonasba@gmail.com> wrote:> Hi, > > I am currently developing a website for selling tickets for events. A big > issue here is concurrency. Multiple user should not be able to buy tickets > at the exact same time and create a inconsistent database where more > tickets have been sold than what was actually available. > > The act of purchasing is a two step process: > > 1. Check that there are enough available tickets left. > 2. Create ticket records representing the users tickets. > > This is a critical part of the system and mutual exclusion must occur. At > the moment, I have created a file based semaphore. Here is an isolated > example of how I do this. The example shows mutual exclusion on a per-event > basis, enabling multiple purchases to occur at the same time, as long as > they are for seperate events. > > https://gist.github.com/4366276 > > This works swimmingly. (And it''s so cool!) But I would much rather like to > utilize database transactions with an isolation level of serializable. I > understand that ActiveRecord::Base#save already [creates a transaction]( > https://github.com/rails/rails/blob/master/activerecord/lib/active_record/transactions.rb#L257 > ). > > To my knowledge, there''s nothing in Rails resembling the possibility to > set the isolation level of an transaction. I think that is an issue. > Isolation level is, in my opinion, a huge part of what transactions are. At > least I could use a feature like that, in my case. > > It would be so awesome if one for instance could do > > transaction.save :isolation => :serializable > > > or > > transaction :isolation => :serializable do >> # … >> end > > > What do you think? > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To view this discussion on the web visit > https://groups.google.com/d/msg/rubyonrails-core/-/5WfQkkKQWvsJ. > To post to this group, send email to rubyonrails-core@googlegroups.com. > To unsubscribe from this group, send email to > rubyonrails-core+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/rubyonrails-core?hl=en. >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
Jonas Amundsen
2012-Dec-23 23:18 UTC
Re: Isolation level for transactions initiated by ActiveRecord::Base#save
On Monday, December 24, 2012 12:08:48 AM UTC+1, Rafael Mendonça França wrote:> > It is already implemented and will be shipped with Rails 4. > > See > https://github.com/rails/rails/commit/392eeecc11a291e406db927a18b75f41b2658253 >Oh, that''s great! It didn''t occur to me to look in edge. I just messed around with 3.2.9. I''ll be looking forward to Rails 4. :) -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-core/-/O2zTd09Zmc4J. To post to this group, send email to rubyonrails-core@googlegroups.com. To unsubscribe from this group, send email to rubyonrails-core+unsubscribe@googlegroups.com. For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.