3

对于该代码,任何人都可以为我提供更好的解决方案:

<?php

try {
    $dbh = new PDO('mysql:host=localhost;dbname=test', $user, $password);

    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $dbh->beginTransaction();

    $dbh->exec("LOCK TABLES test2 WRITE");

    $row = $dbh->query('SELECT * from test2 WHERE c > 0 LIMIT 1');

    $stmt = $dbh->prepare("UPDATE test2 SET c=c-1 WHERE a=:a and c>0");
    $stmt->bindParam(':a', $row['a']);
    $stmt->execute();

    /**
    ...
    ....
    .....
    **/

    $dbh->exec("UNLOCK TABLES");

    $dbh->commit();
    $dbh = null;
} catch (PDOException $e) {
    error_log("Error!: " . $e->getMessage() . "\n", 3, "./my-errors.log");
    exit();
}

当我同时连接到该脚本时,每个连接都应该在表 test2(字段 A)中有自己的行。

感谢您的想法:-)

4

2 回答 2

1

如果您不需要知道a参数,可以使用以下查询

UPDATE test2 SET c=c-1 WHERE c>0 LIMIT 1;
于 2012-08-16T16:44:52.870 回答
0

LOCK TABLESUNLOCK TABLES自动关闭您的交易。您需要一个SELECT .. FOR UPDATE忘记锁定和解锁表。

SELECT FOR UPDATE行级别的锁。如果他们假装获得相同的记录,则其他执行SELECT FOR UPDATE将等待第一次转换的结束。

于 2013-02-18T12:33:41.163 回答