Rails/Postgres - 我需要什么类型的数据库锁?
Rails/Postgres - What type of DB lock do I need?
我有一个 PendingEmail
table,我将许多记录推送到其中以获取我要发送的电子邮件。
然后我有多个 Que 工作人员处理我的应用程序的工作。其中一份工作是我的 SendEmailJob
.
这项工作的目的是检查 PendingEmail
,提取 priority
订购的最新 500 个,向我的第 3 方电子邮件提供商发出批量请求,等待所有 500 个响应的数组响应, 然后删除成功的项目并标记失败记录的 error
列。单个作业将以这种方式继续,直到从 DB 返回的记录为 0,并且作业将 exit/destroy.
问题是:
- 重要的是一次只有一个
SendEmailJob
处理电子邮件。
- 如果当前
SendEmailJob
不是 运行,我需要每秒检查一次数据库。如果是 运行,则没有问题,因为该作业将在 ~3 秒内完成。
- 如果 table 被锁定(无论如何可能),我的 app/other 工作人员必须仍然能够插入,因为我应用程序的其他部分需要将电子邮件添加到 table.我主要只是需要限制我觉得SELECT。
- 所有这一切都需要快速。我这样做的部分原因是为了提高性能,因为我在短时间内发送了数百万封电子邮件。
- 目前我的工作是用时钟进程(发条)启动的,所以它会每 1 秒添加一次这个工作。
我在想什么...
- Que 已经使用了咨询锁和其他 PG 机制。我宁愿不试图搞砸 table 试图阻止添加多个工作摆在首位。相反,我认为可能有很多
SendEmailJob
可以同时 运行 是可以的,只要它们在有锁的情况下提前中止。
- 显然有一些 Rails 方法可以做到这一点,但我假设我需要直接对 PG 执行代码以在每个作业中启动某种锁定,但在这样做之前它会检查是否已经存在一把锁,如果有则中止)
只是不知道选择哪种类型的锁,是在Rails中做还是直接在数据库中做。它们中有很多具有如此细微的差异(我使用的是 PG)。任何见解将不胜感激!
答案:我需要 advisory lock。
我有一个 PendingEmail
table,我将许多记录推送到其中以获取我要发送的电子邮件。
然后我有多个 Que 工作人员处理我的应用程序的工作。其中一份工作是我的 SendEmailJob
.
这项工作的目的是检查 PendingEmail
,提取 priority
订购的最新 500 个,向我的第 3 方电子邮件提供商发出批量请求,等待所有 500 个响应的数组响应, 然后删除成功的项目并标记失败记录的 error
列。单个作业将以这种方式继续,直到从 DB 返回的记录为 0,并且作业将 exit/destroy.
问题是:
- 重要的是一次只有一个
SendEmailJob
处理电子邮件。 - 如果当前
SendEmailJob
不是 运行,我需要每秒检查一次数据库。如果是 运行,则没有问题,因为该作业将在 ~3 秒内完成。 - 如果 table 被锁定(无论如何可能),我的 app/other 工作人员必须仍然能够插入,因为我应用程序的其他部分需要将电子邮件添加到 table.我主要只是需要限制我觉得SELECT。
- 所有这一切都需要快速。我这样做的部分原因是为了提高性能,因为我在短时间内发送了数百万封电子邮件。
- 目前我的工作是用时钟进程(发条)启动的,所以它会每 1 秒添加一次这个工作。
我在想什么...
- Que 已经使用了咨询锁和其他 PG 机制。我宁愿不试图搞砸 table 试图阻止添加多个工作摆在首位。相反,我认为可能有很多
SendEmailJob
可以同时 运行 是可以的,只要它们在有锁的情况下提前中止。 - 显然有一些 Rails 方法可以做到这一点,但我假设我需要直接对 PG 执行代码以在每个作业中启动某种锁定,但在这样做之前它会检查是否已经存在一把锁,如果有则中止)
只是不知道选择哪种类型的锁,是在Rails中做还是直接在数据库中做。它们中有很多具有如此细微的差异(我使用的是 PG)。任何见解将不胜感激!
答案:我需要 advisory lock。