gpt4 book ai didi

mysql - InnoDB 选择更新

转载 作者:行者123 更新时间:2023-11-29 06:03:10 24 4
gpt4 key购买 nike

如果我有一个 InnoDB 表的简单语句

UPDATE <table> SET locked=1, col2=<Val2> WHERE locked=0

是否真的需要执行 SELECT FOR UPDATE?

由于 InnoDB 支持行级锁定,即使成千上万的客户端同时执行相同的脚本,是否有可能发生冲突?

更新:

像这样可以防止锁

$dbh = new PDO(DSN, DB_USER, DB_PASS);
$dbh->beginTransaction();
$selQuery = $dbh->prepare("SELECT <col> FROM <table> WHERE status=0 LIMIT 1 FOR UPDATE");
$selQuery->bindColumn(<col1>, $col1);
$selQuery->execute();

$selQuery->fetch(PDO::FETCH_BOUND);

$dbh->query("UPDATE <table> SET status=1 WHERE status=0 LIMIT 1");

$dbh->commit();

最佳答案

是的,碰撞总是会发生。所以使用设计模式:

SELECT FOR UPDATE 首先为给定事务中的所有资源,可以防止或缩短死锁情况。

假设以下场景:

  • 进程 A 按 1,2 的顺序更新表 1 和 2
  • 进程 B 按照 2,1 的顺序更新表 1 和 2

现在进程 A 更新表 1,同时进程 B 更新表 2,导致死锁(假设此更新命中了相同的“记录/页面”)。

但是,如果在事务开始时使用 SELECT FOR UPDATE,事务将在开始时阻塞,因为表 2(或表 1,无论哪个更快)无法锁定(还) .这里的关键部分是“在交易开始时”,如果您稍后再做,那么只需运行 UPDATE 就同样有效。

关键始终是保持事务的原子性和快速性:对 SQL 逻辑进行分组,以便它可以使用最少数量的其他代码执行,并尽可能缩短锁定时间。

关于mysql - InnoDB 选择更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43530086/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com