Ruby on rails Rails唯一验证不起作用,后台作业

Ruby on rails Rails唯一验证不起作用,后台作业,ruby-on-rails,database,postgresql,activerecord,sidekiq,Ruby On Rails,Database,Postgresql,Activerecord,Sidekiq,我有一个名为appointment的应用程序模型。在此模型上,有一列名为event_uid,验证如下所示: validates :event_uid, uniqueness: true, allow_nil: true 唯一验证仅在rails应用程序上,而不在数据库postgresql中 我正在使用heroku上sidekiq的后台作业来同步一些远程日历。我不确定发生了什么,但似乎我得到了多条具有重复事件uid值的记录。它们是在同一秒内创建的 我的猜测是,工人身上发生了一些事情,出于某种原因,

我有一个名为appointment的应用程序模型。在此模型上,有一列名为event_uid,验证如下所示:

validates :event_uid, uniqueness: true, allow_nil: true
唯一验证仅在rails应用程序上,而不在数据库postgresql中

我正在使用heroku上sidekiq的后台作业来同步一些远程日历。我不确定发生了什么,但似乎我得到了多条具有重复事件uid值的记录。它们是在同一秒内创建的

我的猜测是,工人身上发生了一些事情,出于某种原因,他们在同一时间被调用,或者队列被冻结,当它返回时,它运行同一个作业两次。我不明白为什么rails会让上述内容通过,可能是因为工作人员在不同的线程上运行起到了一定的作用?。我添加了以下迁移:

add_index :appointments, [:event_uid], unique: true
希望这种事不会再发生。好的,现在问题是:

你觉得这样就够了吗? 如果在后台作业中使用“创建/更新”,则只允许在应用程序级别上存在唯一性/存在性验证是否危险? 猜猜是什么原因导致工人们在同一秒钟内从事同一项工作不止一次?
通常,rails中的验证只在回调期间发生,有时在提交DB上的记录之前发生,是的,如果您添加了一个唯一的索引,这将不会再次发生,因为DB这次将负责,因此即使您再次遇到相同的流/问题,结果也可能是一个错误,表明您不能复制该索引值

鉴于验证器的性质通常是在回调期间调用的,并且没有线程安全意味着它们可以运行在竞争条件下,这种情况发生的频率取决于您的应用程序,您也应该始终在DB上添加验证

与您的工人相关,几个月前,由于Sidekiq的重试流,我遇到了相同的问题,解决方案是在DB端进行验证,并修复在提交回调后运行工人/作业不确定是否使用Sidekiq,但您始终可以使用提交回调后,在对特定对象进行特定操作后,我正在使用我的工作


希望以上帮助 通常,在回调期间,rails中的验证只会在您提交DB上的记录之前进行,如果添加了唯一索引,则不会再次发生验证,因为这次DB将负责,因此即使您再次遇到相同的流/问题,结果也可能是一个错误,表明无法复制该索引值

鉴于验证器的性质通常是在回调期间调用的,并且没有线程安全意味着它们可以运行在竞争条件下,这种情况发生的频率取决于您的应用程序,您也应该始终在DB上添加验证

与您的工人相关,几个月前,由于Sidekiq的重试流,我遇到了相同的问题,解决方案是在DB端进行验证,并修复在提交回调后运行工人/作业不确定是否使用Sidekiq,但您始终可以使用提交回调后,在对特定对象进行特定操作后,我正在使用我的工作


希望以上帮助 Rails唯一性验证长期以来一直是混乱的原因

当您持久化一个用户实例时,Rails将通过运行SELECT查询来验证您的模型,以查看所提供的电子邮件中是否已经存在任何用户记录。 假设记录被证明是有效的,Rails将运行INSERT语句来持久化用户

这意味着,如果您同时选择了多个辅助进程/线程,它们都将返回false并插入记录

大多数情况下,最好在数据库级别上有一个索引,以避免这些竞争条件。但是,您现在还需要处理任何ActiveRecord::RecordNotUnique异常

你觉得这样就够了吗

是的,添加索引是个好主意,但现在还需要处理ActiveRecord::RecordNotUnique

如果在后台作业中使用“创建/更新”,则只允许在应用程序级别上存在唯一性/存在性验证是否危险

这取决于应用程序,但大多数情况下,您也希望有一个db级别的索引

猜猜是什么原因导致工人们在同一秒钟内从事同一项工作不止一次


大多数后台作业库只保证至少有一个作业排队,但不保证只有一个作业排队。您的作业应该始终是可运行多次的。本指南值得一读,尤其是关于Rails的部分。

Rails唯一性验证长期以来一直是困惑的原因

当您持久化一个用户实例时,Rails将通过运行SELECT查询来验证您的模型,以查看所提供的电子邮件中是否已经存在任何用户记录。 假设记录被证明是有效的,Rail s将运行INSERT语句来持久化用户

这意味着,如果您同时选择了多个辅助进程/线程,它们都将返回false并插入记录

大多数情况下,最好在数据库级别上有一个索引,以避免这些竞争条件。但是,您现在还需要处理任何ActiveRecord::RecordNotUnique异常

你觉得这样就够了吗

是的,添加索引是个好主意,但现在还需要处理ActiveRecord::RecordNotUnique

如果在后台作业中使用“创建/更新”,则只允许在应用程序级别上存在唯一性/存在性验证是否危险

这取决于应用程序,但大多数情况下,您也希望有一个db级别的索引

猜猜是什么原因导致工人们在同一秒钟内从事同一项工作不止一次

大多数后台作业库只保证至少有一个作业排队,但不保证只有一个作业排队。您的作业应该始终是可运行多次的。这本指南值得一读,尤其是关于的部分