ruby-on-rails - 当在 Sidekiq 中引发错误时,如何丢弃在异步任务上执行的所有更改?
问题描述
我正在使用 Sidekiq 和 Rails (6.0.3.7)。我有一个工作人员执行异步任务,该任务按顺序在我的数据库上创建大量数据。所以基本上它会发生什么,例如:
- 首先,它创建一个 User,然后它创建一个 PostCategory,然后它创建一个 Post,然后它创建 10 条评论。
有时,此过程会在中途失败,可能是在创建 PostCategory 或创建 Post 时。
我想要发生的是,如果任务在任何给定点失败,则已在所述任务中创建的所有数据都将被丢弃。另一种方法可能是仅在我确定该过程没有失败时才创建所有数据。所以基本上它必须在实际写入数据库之前“检查创建”所有内容。
这方面的一个例子是 User 已创建,但由于某种原因,它未能创建 PostCategory,并且 AsyncTask 失败。我想要发生的是它会自动删除创建的用户,或者它从来没有被创建,因为任务失败了。
有没有什么方法或技术可以在我当前的工作人员身上做到这一点,而不会过多地使用实际代码?Sidekiq 上已经实现了一些“双重检查”方法?你建议我应该研究什么?
提前感谢您在此问题上给我的任何帮助。
解决方案
首先,太好了,您将任务设计为全有或全无。主要且更可取的方法是使用数据库事务,因为这是它们的设计目的。在开始创建实体之前打开事务,并在所有检查完成后提交。
Account.transaction do
balance.save!
account.save!
end
注意 bang 方法(带有尾随的方法!
)它们的目的是抛出异常。异常会自动回滚事务,这就是您所需要的。
注意 尝试使您的任务具有幂等性,这意味着无论使用相同输入结果的调用次数如何,都返回相同的结果。这可以在未来节省大量时间。
推荐阅读
- java - 预期为 BEGIN_ARRAY,但在第 1 行第 2 列路径 $
- java - Java中ListenableFuture的默认执行器是什么?
- javascript - 如何通过匹配所有值而不是一个值来过滤对象数组
- javascript - 将列表子项传递给父项
- asp.net-mvc - 如何在asp.net核心的一个解决方案中定义的2个项目中定义(控制器/方法)的路由?
- javascript - 在 localStorage 中存储用户 API 密钥的最佳实践
- android - 如何在下面的 android webview api 19 中使用 chrome DevTools?
- ionic-framework - Ionic 3 如何修复离子幻灯片的第一张幻灯片,其中应该显示规格和用户在报价之间滑动以进行比较?
- javascript - Javascript ES6 - 是否可以在子类中不使用 this 关键字的情况下使用/调用超类属性或函数
- xamarin - 使用 Xamarin.Forms MessagingCenter 在 ViewModel 和方法之间进行通信有什么优点或缺点吗