I get an exception and I want to understand why. I’ve created a git repo so anyone can test it.
The rails app is fresh with Devise installed on it.
Running the app and this script that try to create the same user:
1000.times do
fork do
`curl -d "user[email]=your@mail.com&user[password]=pwd&user[password_confirmation]=pwd" localhost:3000/users`
end
end
I get the follow exception:
An ActiveRecord::RecordNotUnique occurred in registrations#create:
Mysql2::Error: Duplicate entry 'your@mail.com' for key 'index_users_on_email': INSERT INTO `users` (`authentication_token`, `confirmation_sent_at`, `confirmation_token`, `confirmed_at`, `created_at`, `current_sign_in_at`, `current_sign_in_ip`, `email`, `encrypted_password`, `failed_attempts`, `last_sign_in_at`, `last_sign_in_ip`, `locked_at`, `remember_created_at`, `reset_password_sent_at`, `reset_password_token`, `sign_in_count`, `unconfirmed_email`, `unlock_token`, `updated_at`) VALUES (NULL, '2013-01-24 16:48:23', 'GQwbJzsawxRsbvhp1LkR', NULL, '2013-01-24 16:48:23', NULL, NULL, 'your@mail.com', '$2a$10$koMNiiZQuhkeWhmYV8PtcOUlvi6rZHTKMs82MGWNa2M/GsUQ0cIHO', 0, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, '2013-01-24 16:48:23')
activerecord (3.2.11) lib/active_record/connection_adapters/abstract_mysql_adapter.rb:245:in `query'
Why I get this exception and not a validation error? If I try to create an user with an email that is already used from the web page “http://localhost:3000/users/sign_up” I dont get this exception but a validation error…
If I run the script without fork (request are sequential), I get no error.
Seems a race conditions problem.
In your script you try to create 1000 users all with the email “your@mail.com”. You have a uniqueness constraint on your user email index (correctly – you only want one user per email address). The second time it tries to create a user with that email you will get the error.
As you are forking your request the
validates_uniqueness_ofvalidation provided by devise may be succeeding because it queries for another record with the same email. But, by the time the record is actually written, another record may exist.For example,