# Validates\_uniqueness\_of and create atomicity

**URL:** <https://www.ruby-forum.com/t/validates-uniqueness-of-and-create-atomicity/60144>\
**Category:** Rails\
**Created:** [May 10, 2006, 5:52pm UTC](https://www.ruby-forum.com/t/validates-uniqueness-of-and-create-atomicity/60144 "2006-05-10T17:52:28Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bosko\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/b77776/32.png) [@Bosko\_M](https://www.ruby-forum.com/u/Bosko_M)\
**Post date:** [May 10, 2006, 5:52pm UTC](https://www.ruby-forum.com/t/validates-uniqueness-of-and-create-atomicity/60144/1 "2006-05-10T17:52:28Z")

</div>

Hi folks,

I have a question regarding validates\_uniqueness\_of, and similar  
before-filter-like events attempting to guarantee some DB state prior  
to modification.

> From my reading of ActiveRecord, validate\_uniqueness\_of appears to  
> cause a SELECT on the underlying table attempting to ensure that a  
> record with ID(s) specified in the validates\_uniqueness\_of statement  
> is not already present, prior to the INSERT (or UPDATE). However, in  
> between the SELECT and INSERT, an offending record might appear.

example race condition scenario:

A) dispatcherInstance1 is to perform a create on entity Foo, which has  
a validates\_uniqueness\_of

B) dispatcherInstance2 is to perform a create on entity Foo with the  
same parameters as in A

C) dispatcherInstance1 enters the validation code and performs its  
SELECT, it decides everything is OK

D) dispatcherInstance2 enters the validation code and performs its  
SELECT, it decides everything is OK

E) dispatcherInstance1 succeeds with its INSERT

F) dispatcherInstance2 either raises exception because DB implements  
uniqueness property as well or inserts duplicate record

So I guess the question is what is the point of  
validates\_uniqueness\_of if it doesn’t guarantee uniqueness? I had  
imagined it would do something “clever” like attempt the insert, trap  
an exception if it occurs, and attempt to subsequently verify if the  
exception is the result of a violation of the uniqueness condition  
specified. But clearly this is not what is happening.

## Regards,

Bosko M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Bosko\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/b77776/32.png) [@Bosko\_M](https://www.ruby-forum.com/u/Bosko_M)\
**Post date:** [May 10, 2006, 7:52pm UTC](https://www.ruby-forum.com/t/validates-uniqueness-of-and-create-atomicity/60144/2 "2006-05-10T19:52:58Z")

</div>

To further follow up on this: what I find myself doing now in order to  
completely guarantee atomicity for the check-and-insert, is simply  
bypass the check (i.e., not enforce validates\_uniqueness\_of) and catch  
exceptions raised due to the insert failing (realizing that such  
exceptions are probably the result of a duplicate key violation on the  
unique index in my [PostgreSQL] DB). This completely guarantees that  
my application doesn’t barf up (with a wierd internal server error)  
but fails “politely” should the admittedly rare race condition  
scenario below actually occur.

–  
Bosko M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Bosko\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/b77776/32.png) [@Bosko\_M](https://www.ruby-forum.com/u/Bosko_M)\
**Post date:** [May 10, 2006, 8:39pm UTC](https://www.ruby-forum.com/t/validates-uniqueness-of-and-create-atomicity/60144/3 "2006-05-10T20:39:18Z")

</div>

On May 10, 2006, at 8:46 AM, Bosko M. wrote:

> between the SELECT and INSERT, an offending record might appear.  
> Yes, it should obtain a write lock on the entire table to ensure its  
> uniqueness check is valid. Clearly this is a poor idea.

> So I guess the question is what is the point of  
> validates\_uniqueness\_of if it doesn’t guarantee uniqueness? I had  
> imagined it would do something “clever” like attempt the insert, trap  
> an exception if it occurs, and attempt to subsequently verify if the  
> exception is the result of a violation of the uniqueness condition  
> specified. But clearly this is not what is happening.

That sounds good. Would you care to pursue an implementation?

jeremy

---

<div class="post-metadata">

**Author:** ![Bosko\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/b77776/32.png) [@Bosko\_M](https://www.ruby-forum.com/u/Bosko_M)\
**Post date:** [May 10, 2006, 9:13pm UTC](https://www.ruby-forum.com/t/validates-uniqueness-of-and-create-atomicity/60144/4 "2006-05-10T21:13:11Z")

</div>

On 5/10/06, Jeremy K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:  
[…]

> > So I guess the question is what is the point of  
> > validates\_uniqueness\_of if it doesn’t guarantee uniqueness? I had  
> > imagined it would do something “clever” like attempt the insert, trap  
> > an exception if it occurs, and attempt to subsequently verify if the  
> > exception is the result of a violation of the uniqueness condition  
> > specified. But clearly this is not what is happening.
> 
> That sounds good. Would you care to pursue an implementation?
> 
> jeremy

Yes, I’ve thought about a possible implementation. I’ll whip up a  
diff and propose it. I decided to not touch the current  
validates\_uniqueness\_of but implement it in the form of a  
guarantee\_uniqueness\_of. It’s a little tricky because it is difficult  
to determine that the exception raised by the create\_or\_update in  
ActiveRecord::Base’s save method is due to a unique index violation –  
what I do is attempt a SELECT following the exception to verify that  
the first one was indeed due to a unique record violation. It works  
but needs a little bit of cleaning up.

–  
Bosko M. | removed\_email\_address@domain.invalid | removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![Bosko\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/b77776/32.png) [@Bosko\_M](https://www.ruby-forum.com/u/Bosko_M)\
**Post date:** [July 30, 2006, 1:28am UTC](https://www.ruby-forum.com/t/validates-uniqueness-of-and-create-atomicity/60144/5 "2006-07-30T01:28:11Z")

</div>

On 5/10/06, Bosko M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > jeremy

Hrm, it’s been a while since we last discussed this.

I did not forget. In fact, I have a local implementation in the form  
of an unpublished plugin I named  
“validates\_uniqueness\_of\_unique\_fields”, but I’m not perfectly happy  
with it because it is too dependent on PostgreSQL being used as the db  
connection adapter (unfortunately there is no way to detect in a  
standard fashion whether the StatementInvalid exception raised by the  
save is actually due to a duplicate key violation). It works, though,  
and I use it in conjunction with validates\_uniqueness\_of since I am  
terribly paranoid (i’ve inline-included a code snippet below if you  
are curious).

I continue to use this in conjunction with UNIQUE db constraints in  
Postgres because the fact is that checking for uniqueness is not a  
validation in the classic sense (it is only partly a validation) –  
unlike other validations, a uniqueness guarantee must be checked  
against not only client-provided data but the DB backing store, which  
makes it significantly more involved than, say,  
validates\_confirmation\_of, or any other validations for that matter.

← snippet →   
module ValidatesUniquenessOfUniqueFields

```
def self.included(base)
  base.extend ValidatesUniquenessOfUniqueFieldsMacro
end

module ValidatesUniquenessOfUniqueFieldsMacro
  def validates_uniqueness_of_unique_fields(msg = nil)
    unless 

```

method\_defined?(:\_\_old\_save\_validates\_uniqueness\_of\_unique\_fields)  
alias\_method  
:\_\_old\_save\_validates\_uniqueness\_of\_unique\_fields, :save  
define\_method :save do  
begin  
\_\_old\_save\_validates\_uniqueness\_of\_unique\_fields  
rescue ActiveRecord::StatementInvalid  
error\_msg = $!.to\_s  
if error\_msg.match(/duplicate/) and  
error\_msg.match(/unique/)  
msg = “Record clashes with one or more unique fields”  
if msg.nil?  
errors.add\_to\_base(msg)  
false  
else  
raise $!  
end  
end  
end  
end  
end  
end

end  
 ← snippet →
