测试 MySQL 锁定是否正常工作

发布于 2024-12-13 04:03:07 字数 525 浏览 4 评论 0原文

我有一个名为 events 的表,其中包含游戏中的事件,例如建筑、研究等。每个事件都有一个 时间戳 指示其完成时间。引擎:innoDB

每次页面加载时,程序都会在 events 表中快速搜索 timestamp 过去的行(即事件已完成)。它选择这些行,然后删除它们,以便任何其他运行都看不到和处理相同的事件。

我担心的是,如果发生两个 pagelod,以便在一个或另一个有机会删除读取的行之前,两个 pagelod 都读取相同的行,以及如果在选择和删除之间发生事件会发生什么。

我认为应该解决它的是:

SET @now=NOW();
SELECT * FROM `events` WHERE `timestamp` < @now FOR UPDATE
DELETE FROM `events` WHERE `timestamp` < @now

但我在测试它时遇到了一些麻烦。我将如何测试这是否按预期工作?

I have a table named events, which contains in-game events such as construction of buildings, research, etc.. Each event has a timestamp indicating when it completes. Engine: innoDB

Every pageload, the program runs a quick search of the events table for rows where timestamp is in the past (ie. the event has been completed). It selects these rows then deletes them so any other runs don't see and process the same events.

What I'm worried about is what would happen if two pagelods happened so that both of them read the same rows before one or the other has a chance to delete the read rows, and what if an event happens right between selecting and deleting.

What I'm thinking should fix it is:

SET @now=NOW();
SELECT * FROM `events` WHERE `timestamp` < @now FOR UPDATE
DELETE FROM `events` WHERE `timestamp` < @now

But I'm having some trouble testing it. How would I go about testing whether or not this is working as it should?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清音悠歌 2024-12-20 04:03:07

要在这里回答我自己的问题:p

selectdelete 之间使用 sleep(),并同时进行两个调用。

最终代码:

START TRANSACTION
SET @now=NOW()
SELECT * FROM `events` WHERE `timestamp` < @now FOR UPDATE
-- SLEEP(5)
DELETE FROM `events` WHERE `timestamp` < @now

结果:

0.000:开始交易
0.001:查询运行,返回 5 行。
5.002:删除了 5 行。
5.008:结束交易
===== 第二次通话,在第一次通话后几秒钟开始:
0.000:开始交易
2.562:查询运行,返回 0 行。
2.562:删除了 0 行。
2.562:结束交易

这与睡眠有关。如果没有睡眠,两者都会在 0.002 秒内结束。

Going to answer my own question here :p

Use sleep() between the select and delete, and have two calls at the same time.

Final code:

START TRANSACTION
SET @now=NOW()
SELECT * FROM `events` WHERE `timestamp` < @now FOR UPDATE
-- SLEEP(5)
DELETE FROM `events` WHERE `timestamp` < @now

Results:

0.000: Starting transaction
0.001: Query run, returned 5 rows.
5.002: Deleted 5 rows.
5.008: Ending transaction
===== Second call, started a couple seconds after the first:
0.000: Starting transaction
2.562: Query run, returned 0 rows.
2.562: Deleted 0 rows.
2.562: Ending transaction

That's with the sleep. Without the sleep both end in under 0.002 seconds.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文