# Efficient Concurrency?

**URL:** <https://www.ruby-forum.com/t/efficient-concurrency/175800>\
**Category:** Rails\
**Created:** [September 20, 2009, 2:28am UTC](https://www.ruby-forum.com/t/efficient-concurrency/175800 "2009-09-20T02:28:44Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Florian\_Dejako](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/f6c823/32.png) [@Florian\_Dejako](https://www.ruby-forum.com/u/Florian_Dejako)\
**Post date:** [September 20, 2009, 2:28am UTC](https://www.ruby-forum.com/t/efficient-concurrency/175800/1 "2009-09-20T02:28:44Z")

</div>

My app sends out activation keys from a list of unassigned keys to  
customers. An appropriate model action in the activation key model  
would look something like this:

named\_scope :available, :conditions =\> ‘available IS NULL’

def fetch\_available\_key  
key = ActivationKey.available.first  
key.assigned = DateTime.now  
key.save  
return key  
end

What’s the best way to deal with concurrent requests in this  
situation? My deployment server uses passenger, the database is MySQL  
5.x.

Thanks,

Florian

---

<div class="post-metadata">

**Author:** ![Florian\_Dejako](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/f6c823/32.png) [@Florian\_Dejako](https://www.ruby-forum.com/u/Florian_Dejako)\
**Post date:** [September 21, 2009, 4:57pm UTC](https://www.ruby-forum.com/t/efficient-concurrency/175800/2 "2009-09-21T16:57:33Z")

</div>

Florian Dejako wrote:

> My app sends out activation keys from a list of unassigned keys to  
> customers. An appropriate model action in the activation key model  
> would look something like this:
> 
> named\_scope :available, :conditions =\> ‘available IS NULL’
> 
> def fetch\_available\_key  
> key = ActivationKey.available.first  
> key.assigned = DateTime.now  
> key.save  
> return key  
> end
> 
> What’s the best way to deal with concurrent requests in this  
> situation? My deployment server uses passenger, the database is MySQL  
> 5.x.

I’ve never quite done this, but from the docs it seems that you probably  
want pessimistic locking. Make sure that you’re using a mySQL storage  
engine that supports the appropriate features; better yet, try switching  
to PostgreSQL.

> Thanks,
> 
> Florian

## Best,

Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![Florian\_Dejako](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/f6c823/32.png) [@Florian\_Dejako](https://www.ruby-forum.com/u/Florian_Dejako)\
**Post date:** [September 21, 2009, 5:09pm UTC](https://www.ruby-forum.com/t/efficient-concurrency/175800/3 "2009-09-21T17:09:38Z")

</div>

Frederick C. wrote:

> On Sep 21, 3:57ï¿½pm, Marnen Laibow-Koser \<rails-mailing-l…@andreas-  
> [s.net](http://s.net)\> wrote:
> 
> > > ï¿½ key.save  
> > > to PostgreSQL.
> 
> would have thought that Active Record’s optimistic locking would do  
> the job - if upon saving you get a StaleObjectError you know that you  
> need to try again.

Perhaps it would; I’ve never used ActiveRecord locking at all, so I’ll  
defer to you here. However, I tend to think that locking should  
generally be implemented at the database level, not the application  
level, which is why I suggested pessimistic here. Am I missing  
something?

> Fred

## Best,

Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![Florian\_Dejako](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/f6c823/32.png) [@Florian\_Dejako](https://www.ruby-forum.com/u/Florian_Dejako)\
**Post date:** [September 21, 2009, 5:04pm UTC](https://www.ruby-forum.com/t/efficient-concurrency/175800/4 "2009-09-21T17:04:53Z")

</div>

On Sep 21, 3:57 pm, Marnen Laibow-Koser \<rails-mailing-l…@andreas-  
[s.net](http://s.net)\> wrote:

> > key.save  
> > to PostgreSQL.

would have thought that Active Record’s optimistic locking would do  
the job - if upon saving you get a StaleObjectError you know that you  
need to try again.

Fred

---

<div class="post-metadata">

**Author:** ![Florian\_Dejako](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/f6c823/32.png) [@Florian\_Dejako](https://www.ruby-forum.com/u/Florian_Dejako)\
**Post date:** [September 21, 2009, 5:42pm UTC](https://www.ruby-forum.com/t/efficient-concurrency/175800/5 "2009-09-21T17:42:21Z")

</div>

On Sep 21, 4:09 pm, Marnen Laibow-Koser \<rails-mailing-l…@andreas-  
[s.net](http://s.net)\> wrote:

> Perhaps it would; I’ve never used ActiveRecord locking at all, so I’ll  
> defer to you here. However, I tend to think that locking should  
> generally be implemented at the database level, not the application  
> level, which is why I suggested pessimistic here. Am I missing  
> something?

Well with optimistic locking it is ultimately the database enforcing  
stuff - after all it is the only thing that can. If my memory is  
correct the docs for optimistic locking have a decent explanation of  
how it works.

Fred

---

<div class="post-metadata">

**Author:** ![Florian\_Dejako](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/f6c823/32.png) [@Florian\_Dejako](https://www.ruby-forum.com/u/Florian_Dejako)\
**Post date:** [September 21, 2009, 7:03pm UTC](https://www.ruby-forum.com/t/efficient-concurrency/175800/6 "2009-09-21T19:03:11Z")

</div>

On 21 Sep 2009, at 17:48, Marnen Laibow-Koser wrote:

> > > something?  
> > > _stored_ in  
> > > the DB, but the DB knows nothing about using it for lock enforcement.)

when you do a save with optimistic locking it appends a " where  
lock\_version=expected\_version" to the update query, so yes it is up to  
the app to append that, but the ultimate decision of ‘has lock\_version  
changed’ will fall to the db.

> Pessimistic locking, by contrast, uses the DB’s native locking  
> mechanisms. This makes it far more airtight than optimistic, I think.  
> Anyway, optimistic locking seems like reinventing the square wheel.  
> Why  
> bother?

Because in a case where you expect the lock to almost always succeed  
it’s faster.

Fred

---

<div class="post-metadata">

**Author:** ![Florian\_Dejako](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/f6c823/32.png) [@Florian\_Dejako](https://www.ruby-forum.com/u/Florian_Dejako)\
**Post date:** [September 21, 2009, 8:15pm UTC](https://www.ruby-forum.com/t/efficient-concurrency/175800/7 "2009-09-21T20:15:12Z")

</div>

Thanks for the responses and discussion, everybody! It seems like  
lock\_version should do the trick in my case.

Best,

Florian

---

<div class="post-metadata">

**Author:** ![Florian\_Dejako](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/f6c823/32.png) [@Florian\_Dejako](https://www.ruby-forum.com/u/Florian_Dejako)\
**Post date:** [September 21, 2009, 6:48pm UTC](https://www.ruby-forum.com/t/efficient-concurrency/175800/8 "2009-09-21T18:48:29Z")

</div>

Frederick C. wrote:

> On Sep 21, 4:09ï¿½pm, Marnen Laibow-Koser \<rails-mailing-l…@andreas-  
> [s.net](http://s.net)\> wrote:
> 
> > Perhaps it would; I’ve never used ActiveRecord locking at all, so I’ll  
> > defer to you here. ï¿½However, I tend to think that locking should  
> > generally be implemented at the database level, not the application  
> > level, which is why I suggested pessimistic here. ï¿½Am I missing  
> > something?
> 
> Well with optimistic locking it is ultimately the database enforcing  
> stuff - after all it is the only thing that can. If my memory is  
> correct the docs for optimistic locking have a decent explanation of  
> how it works.

If I understand the docs correctly, optimistic locking is _not_ enforced  
by the database – rather, it’s up to the app to properly handle  
checking and updating the lock\_version field. (The value is _stored_ in  
the DB, but the DB knows nothing about using it for lock enforcement.)

Pessimistic locking, by contrast, uses the DB’s native locking  
mechanisms. This makes it far more airtight than optimistic, I think.  
Anyway, optimistic locking seems like reinventing the square wheel. Why  
bother?

> Fred

## Best,

Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid
