ruby-on-rails - 注册#create 中发生 ActiveRecord::RecordNotUnique 为什么?

标签 ruby-on-rails ruby exception unicorn rails-activerecord

我遇到异常,我想了解原因。我创建了一个 git 存储库,以便任何人都可以测试它。

Rails 应用程序是全新的,上面安装了 Devise。

运行应用程序和此脚本来尝试创建相同的用户:

1000.times do
  fork do
    `curl -d "user[email]<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e2df9b8d9790a28f838b8ecc818d8f" rel="noreferrer noopener nofollow">[email protected]</a>&user[password]=pwd&user[password_confirmation]=pwd" localhost:3000/users`
  end
end

我收到以下异常:

An ActiveRecord::RecordNotUnique occurred in registrations#create:

Mysql2::Error: Duplicate entry '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5c2533292e1c313d3530723f3331" rel="noreferrer noopener nofollow">[email protected]</a>' 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, '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="136a7c6661537e727a7f3d707c7e" rel="noreferrer noopener nofollow">[email protected]</a>', '$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'

为什么我收到此异常而不是验证错误?如果我尝试使用已从网页“http://localhost:3000/users/sign_up”使用的电子邮件创建用户,我不会收到此异常,但会收到验证错误...

如果我在没有 fork 的情况下运行脚本(请求是连续的),则不会出现错误。

似乎是竞争条件问题。

最佳答案

在您的脚本中,您尝试创建 1000 个用户,所有用户的电子邮件地址均为“[email protected] ”。您的用户电子邮件索引有唯一性约束(正确的是,每个电子邮件地址只需要一个用户)。第二次尝试使用该电子邮件创建用户时,您将收到错误消息。

当您 fork 请求时,devise 提供的 validates_uniqueness_of 验证可能会成功,因为它会查询具有同一电子邮件的另一条记录。但是,当实际写入记录时,可能存在另一条记录。

例如,

  1. 请求 1 检查现有电子邮件地址“[email protected]” - 好的
  2. 请求对现有电子邮件“[email protected] ”进行 2 次检查 - 好的
  3. 请求 1 使用电子邮件地址“[email protected]”写入记录 - 好的
  4. 请求 2 使用电子邮件地址“[email protected] ”写入记录 - 违反唯一性。

关于ruby-on-rails - 注册#create 中发生 ActiveRecord::RecordNotUnique 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14507029/

相关文章:

ruby-on-rails - 如何摆脱 let using before

visual-studio-2010 - Visual Studio 通过宏启用调试异常

c++ - 无法在 MinGW 中捕获 bad_alloc

ruby-on-rails - 将持续时间转换为小时 :minutes:seconds (or similar) in Rails 3 or Ruby

ruby-on-rails - Heroku 上的 Rails 5.2 - 缺少 Coffee_script

ruby-on-rails - 收集 Rails 应用程序使用统计信息的最佳方式

ruby-on-rails - TinyTDS : Server name not found in configuration files

ruby-on-rails - 在 ActiveRecord 模型类中重新加载列名称

ruby - N % 2 中的 % 运算符在 Ruby 中做什么?

javascript - 日志显示错误对象 : {"isTrusted":true} instead of actual error data