我的 SQL 5.6 - 如何防止读取先前 SQL 语句选择的行加上在给定列中共享重复值的任何其他行
My SQL 5.6 - how to prevent Reads on rows selected by a previous SQL statement PLUS any other row which share a duplicate value in a given column
我有一个非常具体且相当复杂的需求来防止来自不同服务器的大规模并发(同一秒,有时是同一毫秒)请求的读取(到准确地说,它们是 AWS lambdas)在一个名为 Hobby_ideas_articles.
的 table 上
设置:
mySQL 5.6
on aws aurora serverless MySQL(自动提交默认关闭)
我当然阅读了很多关于行锁的帖子,并认为它们可能是解决方案的一部分,但我认为我不属于基本的 select...for update
案例。
我的 table 是 Hobby_ideas_articles
并且有如下记录:
hobby_idea_article_id= 1,
hobby_id = 6
url= 'http://exo.example.com',
author = 'john@example.com'
hobby_idea_article_id= 2,
hobby_id = 3
url= 'http://exo.example2.com',
author = 'john@example.com'
hobby_idea_article_id= 3,
hobby_id = 7
url= 'http://exo.example3.com',
author = 'eric@example.com'
我还有另一个名为 Past_Customer_sent_messages
的 table,其中的记录如下:
past_customer_sent_message_id = 5
hobby_id = 7,
customer_id = 4,
recipient = "john@example.com",
sent_at= "2019-09-10 00:00:00"
past_customer_sent_message_id = 6
hobby_id = 999,
customer_id = 4,
recipient = "eric@example.com",
sent_at= "2019-09-18 00:00:00"
past_customer_sent_message_id = 7
hobby_id = 999,
customer_id = 4,
recipient = "nestor@example.com",
sent_at= "2019-07-18 00:00:00"
我今天有一个有效的 SQL 语句,基于 2 个输入(hobby_id
和 customer_id
)(每个输入的不同值lambdas), 将使用给定的 hobby_id
和 exclude/filter 获取所有 Hobby_ideas_articles
在最近向作者发送消息时的任何结果(由任何客户在 x 天内和特定customer_id
在 y 小时内)(详细了解这些 conditions/restrictions 的细节:)。
SELECT
hia.hobby_idea_article_id,
hobby_id,
url,
author,
ces.sent_at
FROM
Hobby_ideas_articles hia
LEFT JOIN
Past_Customer_sent_messages ces
ON
hia.author = ces.recipient
WHERE
hia.hobby_id = HOBBY_ID_INPUT_I_HAVE AND
hia.author IS NOT NULL
AND hia.author NOT IN (
SELECT recipient
FROM Past_Customer_sent_messages
WHERE
(
customer_id = CUSTOMER_ID_INPUT_I_HAVE
AND sent_at > DATE_SUB(NOW(), INTERVAL 30 DAY)
) OR
(
sent_at > DATE_SUB(NOW(), INTERVAL 3 HOUR
)
)
)
GROUP BY hia.author
ORDER BY hia.hobby_idea_article_id ASC
LIMIT 20
这意味着例如:
- 在 10:05:03 上午,lambda 将执行
hobby_idea_article_id= 4
和 customer_id= 7
的语句
- at 10:05:04am,就在亚毫秒之后,另一个 lambda 将执行
hobby_idea_article_id= 12
和 customer_id= 8
的语句
...等等...
唯一的 "business logic" 保证是 我永远不会有 2 个具有相同输入对的并发 lambdas (hobby_id
, customer_id
) .
所以当前的 SO 问题是关于 如何确保客户在处理即将到来的请求时永远不会向同一个收件人发送两封快速电子邮件(一封紧接另一封仅几秒钟)来自大规模并发 lambdas ?
问题的一个例子是:
在 10:05:03 am,lambda 为 hobby_id= 4
和 customer_id=
3 执行 SQL 语句
并检索这些数据:
hobby_idea_article_id= 2,
hobby_id = 4
url= 'http://exo.example2.com',
作者 = 'john@example.com'
hobby_idea_article_id= 3,
hobby_id = 4
url= 'http://exo.example3.com',
作者 = 'eric@example.com'
这意味着我将在几秒钟后发送 john@example.com
和 eric@example.com
一封电子邮件(由另一个 lambda 执行,负责处理传递给它的数据的电子邮件)
在 10:05:03 上午,一个并行的 lambda 在同一时间执行 second/ms 执行 SQL 语句hobby_idea_article_id= 4
和 customer_id= 7
(事实上,我可以有 8 个客户想要关于爱好“使用 Id=4 钓鱼!”的想法)。此 lambda 检索与第一个 lambda(正如您在 SQL 语句中看到的那样,customer_id
输入仅用于过滤作者,如果他们已经收到该特定客户的消息)。为了示例,我们假设它过滤掉了 john
,因为 john
已经在 12 天前被客户用 customer_id=
7 发送了消息,所以这里检索到的数据是:
hobby_idea_article_id= 3,
hobby_id = 4
url= 'http://exo.example3.com',
author = 'eric@example.com'
这意味着我将在几秒钟后向 eric@example.com 发送一封电子邮件(由传递此数据的另一个 lambda 执行)
问题是:eric@example.com 将收到 2 封快速电子邮件,但我绝对不想允许这样的事情发生。我在当前 SQL 声明中实施的保护措施(请参阅条件 1 和 2 解释 ),仅当我可以使用有关已在 [= 上发送的电子邮件的持久信息时,才能防止这些重复的快速电子邮件299=] 但由于这种情况发生得如此接近/如此同时发生,第二个 lambda 将看不到已经(或者更准确地说 "is going to be " 几秒钟后另一个 lambda 发送了一条消息到 eric@example.com
。
我需要确保第二个 lambda 不会输出带有 author=eric 的 hobby_idea 以防止此类双重电子邮件。
我有两个想法解决方案,但我认为第二个更好,因为第一个有问题。
1.解决方案 1 - 使用带有 select ...for update
?
的行锁
这样,当第一个 lambda 命中 SQL 时,它将阻止对 SQL 查询输出行的所有行进行读取,如果我理解正确的话,使它们成为 "invisible" 到任何后续的 SELECT。这意味着如果第二个 lambda 同时到达,第一个 lambda 的 SQL 语句行的结果将不是偶数 considered/found!
读完之后,我考虑在 transaction 中进行操作,并移动所有 hobby_idea_articles,这是第一个 SQL 语句的结果状态"currently_locked_for_emailing",赋值true
,然后通过"commiting"交易解锁
然后,当我实际上已经从另一个 lambda 发送了电子邮件,并且只有在 persisted/written 在 Past_Customer_sent_messages table 上的数据库上实际发送了关于这封电子邮件的数据之后* *, 我会把 'currently_locked_for_emailing' 的状态改回 false
**.
在这种情况下,行锁对我很有用,可以确保在我更改/更新状态(几毫秒)时,确保没有其他 lambda 可以读取数据。
下面的 SQL 语句行得通吗?注意 'currently_locked_for_emailing'
上的事务和新的 WHERE 子句
-- (A) start a new transaction
START TRANSACTION;
-- (B) Get the latest order number
SELECT
hia.hobby_idea_article_id,
hobby_id,
url,
author,
ces.sent_at
FROM
Hobby_ideas_articles hia
LEFT JOIN
Past_Customer_sent_messages ces
ON
hia.author = ces.recipient
WHERE
hia.hobby_id = HOBBY_ID_INPUT_I_HAVE AND
hia.author IS NOT NULL
AND hia.author NOT IN (
SELECT recipient
FROM Past_Customer_sent_messages
WHERE
(
customer_id = CUSTOMER_ID_INPUT_I_HAVE
AND sent_at > DATE_SUB(NOW(), INTERVAL 30 DAY)
) OR
(
sent_at > DATE_SUB(NOW(), INTERVAL 3 HOUR
)
)
) AND
# NEW CLAUSE ON currently_locked_for_emailing
# THAT GOES ALONG WITH THE ROW LOCK STRATEGY
hia.currently_locked_for_emailing = false
GROUP BY hia.author
ORDER BY hia.hobby_idea_article_id ASC
LIMIT 20
# ADD THE NEW FOR UPDATE FOR THE ROW LOCK
FOR UPDATE
-- (C). Update the column `currently_locked_for_emailing` to `true`
UPDATE Hobby_ideas_articles
SET currently_locked_for_emailing = true
WHERE
############### how to say do it for all the same rows which are the result of the
previous SQL statement on above (see (B)
-- (D) commit changes
COMMIT;
1.1 你能帮我修复上面的SQL代码吗?
1.2 放锁后更新currently_locked_for_emailing
到true
感觉不对但是之前怎么办?
1.3 我也不知道如何断言'请将所有行的 currently_locked_for_emailing
更改为 true
,这是 SQL 的结果在 (A) 里面 ?
1.4如何进行"unlock"交易?确实在更新 currently_locked_for_emailing 状态后,我可以解锁 ti 进行读写,但如何做到这一点?事实上,我不想等待与服务器的连接结束。请确认锁定将在 (D) 到达交易 'COMMIT' 后立即移除?
1.5 上面的代码只锁定所有作为 SELECT 结果输出的行而不是整个 table 的所有行是否正确?
如果是,是否意味着通过使用LIMIT 20,它只会锁定结果的20行,而不是所有匹配的行(我的意思是对应于WHERE子句),没关系,但我想确定这一点。
1.6 我读了很多 OT SO 帖子 (here, that for a row lock to work, you must absolutely have an index... One person even says here "My own tests show that using for update with where filters on non-indexed columns results in whole-table locking, while with where filters on indexed columns results in the desired behaviour of filtered row locking. "
是真的吗,那我应该把它放在什么上面,它不像我的 where 是一个简单的 1 列或两列...我所有 where 子句列上的索引会非常复杂不是吗?
2。解决方案 2 - 补充 select...更新,因为即使我得到 1. 正确,我仍然有一个重要问题:
如果我正确理解 'row lock' 锁定了 SELECT 结果内的所有行,那么问题就出在这里。 但我需要的真正锁不仅是 select 结果的行,而且我需要对作者具有相同值的任何行放置行锁在 SELECT
的结果中
让我用一个例子来解释为什么,我使用与 1 相同的数据。
在 10:05:03 上午,lambda 为 hobby_id= 4 和 [=156 执行 SQL 语句=]customer_id= 3
并检索这些数据:
hobby_idea_article_id= 2,
hobby_id = 4
url= 'http://exo.example2.com',
author = 'john@example.com'
hobby_idea_article_id= 3,
hobby_id = 4
url= 'http://exo.example3.com',
author = 'eric@example.com'
...这意味着我将在几秒钟后向 john@example.com
和 eric@example.com
发送一封电子邮件(由传递此数据的另一个 lambda 执行)
- 随着 1. 的行锁解决方案的实施,我们现在知道第二个 lambda 将无法 select 上面的前 2 条记录 hobby_idea_article_id 2 和 3)(酷! ) 因为它会:
- 或者运行进入行锁(这些行对他来说是不可见的)如果事情非常非常并发地发生,
- OR因为它不会select他们因为他们现在有
'currently_locked_for_emailing'= true
(见新的SQL语句WHERE子句currently_locked_for_emailing = 'false'
,
- 或 因为电子邮件已发送,我们已经坚持它已在 Past_Customer_sent_messages.
上发送的事实
...但是我还有个大问题
在 10:05:03 上午,第二个 lambda 执行 SQL 语句 hobby_id= 9 (这是另一个爱好,这是我的问题的核心) 和 customer_id= 13 并检索这些数据:
hobby_idea_article_id= 4,
hobby_id = 9 //the hobby_id is DIFFERENT from the one above
url= 'http://exo.example3.com',
author = 'eric@example.com'//but the email recipient is still eric@example.com !!!!
如您所见,我们有一个特殊的情况,因为这里行锁策略不起作用:确实我希望第二个 lambda 不要获取此数据 因为作者是同一个 (eric@example.com
),但它没有被第一个SQL语句锁定,也没有赋值currently_locked_for_emailing= true
因为第一个 SQL 语句有一个 hobby_id=4
的 WHERE 子句......但这里是一个不同的 hobby_id
!!!所以该行从未被锁定,因此行 hobby_idea_article_id= 4
将被抓取,我冒着在几毫秒内向同一收件人发送电子邮件的风险。
所以我不确定该怎么做,但**也许我需要像组合行锁或**双行锁****(不确定这将如何工作)这样的东西'row lock'(直到我用 currently_locked_for_emailing = true
更新)到:
- 首先是 'resulting rows of the SQL statement SELECT'
的行
- 还有
Hobby_ideas_articles
的任何其他行与 SELECT 的结果行之一具有相似的 'author' 值
在第 1 行和第 2 行上,我将应用交易策略并将 currently_locked_for_emailing
设置为 true
(直到发送实际电子邮件并且我在 Past_Customer_sent_messages
上坚持这一事实)
这是正确的做法吗?如何在 SQL 中做到这一点?
免责声明:我来自 Rails 背景,我曾经有 ORM(活动记录)使所有 chains/joins/ 更容易更自动地工作现在的 SQL 复杂语句
我完全迷失了
我必须承认,我还没有完全阅读您的问题,因为它很大,但我对您的问题有所了解。不是将发送部分和SQL部分分开的解决方案吗?因此,创建一个名为队列的新 table,并将所有操作插入到一个新的 table 中。然后,您 运行 一个单独的 cron/task 发送电子邮件,只要在过去 X 分钟内未联系特定用户。这样您就可以保持独特感。
我有一个非常具体且相当复杂的需求来防止来自不同服务器的大规模并发(同一秒,有时是同一毫秒)请求的读取(到准确地说,它们是 AWS lambdas)在一个名为 Hobby_ideas_articles.
的 table 上设置:
mySQL 5.6
on aws aurora serverless MySQL(自动提交默认关闭)
我当然阅读了很多关于行锁的帖子,并认为它们可能是解决方案的一部分,但我认为我不属于基本的 select...for update
案例。
我的 table 是 Hobby_ideas_articles
并且有如下记录:
hobby_idea_article_id= 1,
hobby_id = 6
url= 'http://exo.example.com',
author = 'john@example.com'
hobby_idea_article_id= 2,
hobby_id = 3
url= 'http://exo.example2.com',
author = 'john@example.com'
hobby_idea_article_id= 3,
hobby_id = 7
url= 'http://exo.example3.com',
author = 'eric@example.com'
我还有另一个名为 Past_Customer_sent_messages
的 table,其中的记录如下:
past_customer_sent_message_id = 5
hobby_id = 7,
customer_id = 4,
recipient = "john@example.com",
sent_at= "2019-09-10 00:00:00"
past_customer_sent_message_id = 6
hobby_id = 999,
customer_id = 4,
recipient = "eric@example.com",
sent_at= "2019-09-18 00:00:00"
past_customer_sent_message_id = 7
hobby_id = 999,
customer_id = 4,
recipient = "nestor@example.com",
sent_at= "2019-07-18 00:00:00"
我今天有一个有效的 SQL 语句,基于 2 个输入(hobby_id
和 customer_id
)(每个输入的不同值lambdas), 将使用给定的 hobby_id
和 exclude/filter 获取所有 Hobby_ideas_articles
在最近向作者发送消息时的任何结果(由任何客户在 x 天内和特定customer_id
在 y 小时内)(详细了解这些 conditions/restrictions 的细节:
SELECT
hia.hobby_idea_article_id,
hobby_id,
url,
author,
ces.sent_at
FROM
Hobby_ideas_articles hia
LEFT JOIN
Past_Customer_sent_messages ces
ON
hia.author = ces.recipient
WHERE
hia.hobby_id = HOBBY_ID_INPUT_I_HAVE AND
hia.author IS NOT NULL
AND hia.author NOT IN (
SELECT recipient
FROM Past_Customer_sent_messages
WHERE
(
customer_id = CUSTOMER_ID_INPUT_I_HAVE
AND sent_at > DATE_SUB(NOW(), INTERVAL 30 DAY)
) OR
(
sent_at > DATE_SUB(NOW(), INTERVAL 3 HOUR
)
)
)
GROUP BY hia.author
ORDER BY hia.hobby_idea_article_id ASC
LIMIT 20
这意味着例如:
- 在 10:05:03 上午,lambda 将执行
hobby_idea_article_id= 4
和customer_id= 7
的语句
- at 10:05:04am,就在亚毫秒之后,另一个 lambda 将执行
hobby_idea_article_id= 12
和customer_id= 8
的语句 ...等等...
唯一的 "business logic" 保证是 我永远不会有 2 个具有相同输入对的并发 lambdas (hobby_id
, customer_id
) .
所以当前的 SO 问题是关于 如何确保客户在处理即将到来的请求时永远不会向同一个收件人发送两封快速电子邮件(一封紧接另一封仅几秒钟)来自大规模并发 lambdas ?
问题的一个例子是:
在 10:05:03 am,lambda 为
hobby_id= 4
和customer_id=
3 执行 SQL 语句 并检索这些数据:hobby_idea_article_id= 2, hobby_id = 4 url= 'http://exo.example2.com', 作者 = 'john@example.com'
hobby_idea_article_id= 3, hobby_id = 4 url= 'http://exo.example3.com', 作者 = 'eric@example.com'
这意味着我将在几秒钟后发送 john@example.com
和 eric@example.com
一封电子邮件(由另一个 lambda 执行,负责处理传递给它的数据的电子邮件)
在 10:05:03 上午,一个并行的 lambda 在同一时间执行 second/ms 执行 SQL 语句
hobby_idea_article_id= 4
和customer_id= 7
(事实上,我可以有 8 个客户想要关于爱好“使用 Id=4 钓鱼!”的想法)。此 lambda 检索与第一个 lambda(正如您在 SQL 语句中看到的那样,customer_id
输入仅用于过滤作者,如果他们已经收到该特定客户的消息)。为了示例,我们假设它过滤掉了john
,因为john
已经在 12 天前被客户用customer_id=
7 发送了消息,所以这里检索到的数据是:hobby_idea_article_id= 3, hobby_id = 4 url= 'http://exo.example3.com', author = 'eric@example.com'
这意味着我将在几秒钟后向 eric@example.com 发送一封电子邮件(由传递此数据的另一个 lambda 执行)
问题是:eric@example.com 将收到 2 封快速电子邮件,但我绝对不想允许这样的事情发生。我在当前 SQL 声明中实施的保护措施(请参阅条件 1 和 2 解释 eric@example.com
。
我需要确保第二个 lambda 不会输出带有 author=eric 的 hobby_idea 以防止此类双重电子邮件。
我有两个想法解决方案,但我认为第二个更好,因为第一个有问题。
1.解决方案 1 - 使用带有 select ...for update
?
这样,当第一个 lambda 命中 SQL 时,它将阻止对 SQL 查询输出行的所有行进行读取,如果我理解正确的话,使它们成为 "invisible" 到任何后续的 SELECT。这意味着如果第二个 lambda 同时到达,第一个 lambda 的 SQL 语句行的结果将不是偶数 considered/found!
读完之后,我考虑在 transaction 中进行操作,并移动所有 hobby_idea_articles,这是第一个 SQL 语句的结果状态"currently_locked_for_emailing",赋值true
,然后通过"commiting"交易解锁
然后,当我实际上已经从另一个 lambda 发送了电子邮件,并且只有在 persisted/written 在 Past_Customer_sent_messages table 上的数据库上实际发送了关于这封电子邮件的数据之后* *, 我会把 'currently_locked_for_emailing' 的状态改回 false
**.
在这种情况下,行锁对我很有用,可以确保在我更改/更新状态(几毫秒)时,确保没有其他 lambda 可以读取数据。
下面的 SQL 语句行得通吗?注意 'currently_locked_for_emailing'
上的事务和新的 WHERE 子句-- (A) start a new transaction
START TRANSACTION;
-- (B) Get the latest order number
SELECT
hia.hobby_idea_article_id,
hobby_id,
url,
author,
ces.sent_at
FROM
Hobby_ideas_articles hia
LEFT JOIN
Past_Customer_sent_messages ces
ON
hia.author = ces.recipient
WHERE
hia.hobby_id = HOBBY_ID_INPUT_I_HAVE AND
hia.author IS NOT NULL
AND hia.author NOT IN (
SELECT recipient
FROM Past_Customer_sent_messages
WHERE
(
customer_id = CUSTOMER_ID_INPUT_I_HAVE
AND sent_at > DATE_SUB(NOW(), INTERVAL 30 DAY)
) OR
(
sent_at > DATE_SUB(NOW(), INTERVAL 3 HOUR
)
)
) AND
# NEW CLAUSE ON currently_locked_for_emailing
# THAT GOES ALONG WITH THE ROW LOCK STRATEGY
hia.currently_locked_for_emailing = false
GROUP BY hia.author
ORDER BY hia.hobby_idea_article_id ASC
LIMIT 20
# ADD THE NEW FOR UPDATE FOR THE ROW LOCK
FOR UPDATE
-- (C). Update the column `currently_locked_for_emailing` to `true`
UPDATE Hobby_ideas_articles
SET currently_locked_for_emailing = true
WHERE
############### how to say do it for all the same rows which are the result of the
previous SQL statement on above (see (B)
-- (D) commit changes
COMMIT;
1.1 你能帮我修复上面的SQL代码吗?
1.2 放锁后更新currently_locked_for_emailing
到true
感觉不对但是之前怎么办?
1.3 我也不知道如何断言'请将所有行的 currently_locked_for_emailing
更改为 true
,这是 SQL 的结果在 (A) 里面 ?
1.4如何进行"unlock"交易?确实在更新 currently_locked_for_emailing 状态后,我可以解锁 ti 进行读写,但如何做到这一点?事实上,我不想等待与服务器的连接结束。请确认锁定将在 (D) 到达交易 'COMMIT' 后立即移除?
1.5 上面的代码只锁定所有作为 SELECT 结果输出的行而不是整个 table 的所有行是否正确? 如果是,是否意味着通过使用LIMIT 20,它只会锁定结果的20行,而不是所有匹配的行(我的意思是对应于WHERE子句),没关系,但我想确定这一点。
1.6 我读了很多 OT SO 帖子 (here, that for a row lock to work, you must absolutely have an index... One person even says here "My own tests show that using for update with where filters on non-indexed columns results in whole-table locking, while with where filters on indexed columns results in the desired behaviour of filtered row locking. " 是真的吗,那我应该把它放在什么上面,它不像我的 where 是一个简单的 1 列或两列...我所有 where 子句列上的索引会非常复杂不是吗?
2。解决方案 2 - 补充 select...更新,因为即使我得到 1. 正确,我仍然有一个重要问题:
如果我正确理解 'row lock' 锁定了 SELECT 结果内的所有行,那么问题就出在这里。 但我需要的真正锁不仅是 select 结果的行,而且我需要对作者具有相同值的任何行放置行锁在 SELECT
的结果中让我用一个例子来解释为什么,我使用与 1 相同的数据。
在 10:05:03 上午,lambda 为 hobby_id= 4 和 [=156 执行 SQL 语句=]customer_id= 3 并检索这些数据:
hobby_idea_article_id= 2, hobby_id = 4 url= 'http://exo.example2.com', author = 'john@example.com' hobby_idea_article_id= 3, hobby_id = 4 url= 'http://exo.example3.com', author = 'eric@example.com'
...这意味着我将在几秒钟后向 john@example.com
和 eric@example.com
发送一封电子邮件(由传递此数据的另一个 lambda 执行)
- 随着 1. 的行锁解决方案的实施,我们现在知道第二个 lambda 将无法 select 上面的前 2 条记录 hobby_idea_article_id 2 和 3)(酷! ) 因为它会:
- 或者运行进入行锁(这些行对他来说是不可见的)如果事情非常非常并发地发生,
- OR因为它不会select他们因为他们现在有
'currently_locked_for_emailing'= true
(见新的SQL语句WHERE子句currently_locked_for_emailing = 'false'
, - 或 因为电子邮件已发送,我们已经坚持它已在 Past_Customer_sent_messages. 上发送的事实
...但是我还有个大问题
在 10:05:03 上午,第二个 lambda 执行 SQL 语句 hobby_id= 9 (这是另一个爱好,这是我的问题的核心) 和 customer_id= 13 并检索这些数据:
hobby_idea_article_id= 4, hobby_id = 9 //the hobby_id is DIFFERENT from the one above url= 'http://exo.example3.com', author = 'eric@example.com'//but the email recipient is still eric@example.com !!!!
如您所见,我们有一个特殊的情况,因为这里行锁策略不起作用:确实我希望第二个 lambda 不要获取此数据 因为作者是同一个 (eric@example.com
),但它没有被第一个SQL语句锁定,也没有赋值currently_locked_for_emailing= true
因为第一个 SQL 语句有一个 hobby_id=4
的 WHERE 子句......但这里是一个不同的 hobby_id
!!!所以该行从未被锁定,因此行 hobby_idea_article_id= 4
将被抓取,我冒着在几毫秒内向同一收件人发送电子邮件的风险。
所以我不确定该怎么做,但**也许我需要像组合行锁或**双行锁****(不确定这将如何工作)这样的东西'row lock'(直到我用 currently_locked_for_emailing = true
更新)到:
- 首先是 'resulting rows of the SQL statement SELECT' 的行
- 还有
Hobby_ideas_articles
的任何其他行与 SELECT 的结果行之一具有相似的 'author' 值 在第 1 行和第 2 行上,我将应用交易策略并将currently_locked_for_emailing
设置为true
(直到发送实际电子邮件并且我在Past_Customer_sent_messages
上坚持这一事实)
- 还有
这是正确的做法吗?如何在 SQL 中做到这一点?
免责声明:我来自 Rails 背景,我曾经有 ORM(活动记录)使所有 chains/joins/ 更容易更自动地工作现在的 SQL 复杂语句
我完全迷失了我必须承认,我还没有完全阅读您的问题,因为它很大,但我对您的问题有所了解。不是将发送部分和SQL部分分开的解决方案吗?因此,创建一个名为队列的新 table,并将所有操作插入到一个新的 table 中。然后,您 运行 一个单独的 cron/task 发送电子邮件,只要在过去 X 分钟内未联系特定用户。这样您就可以保持独特感。