1

在我的应用程序中,用户可以将帖子的状态设置为不同的标志,例如“v”-可见、“d”-删除标记等。

这些标志是通过控制器操作设置的。

我有一个批处理过程,可以运行并清理所有标记为删除的帖子。

Post.find(:all, :conditions => ['status = ?', 'd']).each do |p| p.destroy end

此批处理过程每 x 分钟运行一次。

假设用户用'd'标记帖子=>批处理在某些点运行=>在进程运行时用户将帖子标记为'v'。现在在批处理过程中,记录已经成为删除的目标,并且将在 do 循环完成时删除,但标志已通过控制器操作更改。

理想情况下,如果发生这种情况,我不想在批处理过程中删除该帖子。

处理这个问题的最佳方法是什么?

4

1 回答 1

2

你描述的方式,有一个竞争条件。-- 用户可以在帖子已被删除时标记v。并且用户的请求将被忽略。

根据您的目标,有很多方法可以改变这一点:

1) 变化自

Post.find(:all, :conditions => ['status = ?', 'd']).each do |p| p.destroy end
to
Post.find(:all, :conditions => ['status = ?', 'd']).each do |p|
   p.reload
   p.destroy if p.status == 'd' 
end

这将最小化检查状态和删除帖子之间的时间窗口。

2) 将帖子的显示更改为仅在状态不是“d”时显示帖子。这将有效地加快删除速度,因为其他人将有更少的时间将要删除的帖子标记为“v”

3)为了让人们有更长的时间改变主意,每天只运行一次批处理作业,深夜。将帖子标记为 d(待删除)后,以特殊方式显示该帖子,以警告用户该帖子即将被删除。这给了他们最大的时间来撤消删除请求。

4) 永远不要真正销毁数据。(DBMS 存储很便宜。)当帖子被标记为删除时,只需更改一个标志并且不要再次显示它。这使用户可以随时“取消删除”帖子——无需担心最后期限,也无需担心任何竞争条件。

于 2010-09-06T03:10:36.283 回答