Mariadb做选择等待其他交易完成

发布于 2025-02-11 23:15:17 字数 1344 浏览 0 评论 0 原文

我在 Mariadb 10.6.5 上,并且有此代码:

$pdo->query("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;");
$pdo->query("SET autocommit = 0;");

try
{
    $max_id = $pdo->query("SELECT MAX(id) FROM test")->fetchColumn();
    sleep(3);
    $insert_sql = $pdo->prepare("INSERT INTO test(test) VALUES(:test)");
    $insert_sql->execute(['test' => $max_id + 1]);
}
catch (Throwable $e)
{
    $pdo->query("ROLLBACK;");
}

$pdo->query("COMMIT;");

test 表有两个列: id> id (自动增量)& 测试(int)。

当两个用户同时执行此代码时,我希望第一个交易锁定 test 选择语句,以及第二笔交易以等待选择对第一个要完成的语句。 如果一切顺利,则 ID 列应始终等于 test 列。

这可能吗?如果是这样,怎么样?

为了澄清,这是我想发生的事情:

  • 两个用户 u1 u2 同时运行此代码, u1 运行了几微秒早期
  • U1 运行选择语句,锁定表 test
  • u1 运行 insert 语句
  • u1 运行提交语句,解锁表 test
  • u2 运行 select> select 语句,阅读新的 max(id)之后插入 u1> u1
  • u2 运行 insert /code>语句
  • u2 运行提交语句

I'm on MariaDB 10.6.5, and I have this code :

$pdo->query("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;");
$pdo->query("SET autocommit = 0;");

try
{
    $max_id = $pdo->query("SELECT MAX(id) FROM test")->fetchColumn();
    sleep(3);
    $insert_sql = $pdo->prepare("INSERT INTO test(test) VALUES(:test)");
    $insert_sql->execute(['test' => $max_id + 1]);
}
catch (Throwable $e)
{
    $pdo->query("ROLLBACK;");
}

$pdo->query("COMMIT;");

The test table has two columns : id (auto incremented) & test (int).

When two users execute this code at the same time, I want the first transaction to lock the test table at the SELECT statement and for the second transaction to wait at the SELECT statement for the first one to finish.
If everything goes well, the id column should always be equal to the test column.

Is this possible ? And if so, how ?

For clarification, here's what I want to happen :

  • Two users U1 and U2 run this code at the same time, U1 runs it a few microseconds earlier
  • U1 runs the SELECT statement, locking the table test
  • U1 runs the INSERT statement
  • U1 runs the COMMIT statement, unlocking the table test
  • U2 runs the SELECT statement, reading the new MAX(id) after the INSERT of U1
  • U2 runs the INSERT statement
  • U2 runs the COMMIT statement

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

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

发布评论

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

评论(1

夢归不見 2025-02-18 23:15:17

您可以在开始时使用 get_lock

添加查询 do get_lock('lockname',30)在开始时, do resable_lock('lockname')之后询问。

因此,当用户1启动查询时,将设置锁定 lockname ,并且仅在完成后将其释放,如果用户2启动脚本 do get_lock('lockname',30)等待继续释放的锁。

You can use GET_LOCK

add the query DO GET_LOCK('lockname', 30) at the start and DO RELEASE_LOCK('lockname') after the query.

So when User 1 starts the query it sets the lock lockname and only releases it when finished, If User 2 starts the script DO GET_LOCK('lockname', 30) waits for the lock to be released before continuing.

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