如何在mysql中获取更新行的主键?

时间:2015-02-08 14:39:47

标签: php mysql sql pdo transactions

在包含两个表usersapples的数据库中,我想为用户分配一个苹果,然后知道苹果ID。可以将多个苹果分配给一个用户。我在PHP工作。

// users asks for an apple - lets find a vacant one
$apple_id = $dbh->query("SELECT id FROM apple WHERE user_id IS NULL LIMIT 1")->fetchColumn();

// hope fully we found an apple, lets assign it
$sth = $dbh->prepare("UPDATE apple SET user_id = ? WHERE apple_id = ?");
$sth->execute(array($user_id,apple_id));

问题是另一个交易可以选择相同的苹果,然后一个用户将覆盖另一个苹果。 如果我在更新语句中包含AND user_id IS NULL,我冒的是没有获得苹果的风险。

我知道我可以和UPDATE apple SET user_id = ? WHERE user_id IS NULL一起去,但后来我不知道苹果ID。

有没有办法获取更新行的主键? 像lastUpdatedId这样的东西会很好。

但我认为我必须使用交易。但我必须选择哪种隔离级别?可重读?可序列化?为什么?这有什么影响?它会仅锁定行还是整个表?

2 个答案:

答案 0 :(得分:1)

您可以执行以下操作:

update apple
    set user_id = if(@apple_id := apple_id, ?, ?)
    where user_id is null
    limit 1;

select @apple_id;

答案 1 :(得分:0)

SELECT ... FOR UPDATE将产生完全所需的效果:

http://dev.mysql.com/doc/refman/5.0/en/innodb-locking-reads.html

$dbh->beginTransaction();

// users asks for an apple - lets find a vacant one
$apple_id = $dbh->query("SELECT id FROM apple WHERE user_id IS NULL LIMIT 1 FOR UPDATE")->fetchColumn();

// hope fully we found an apple, lets assign it
$sth = $dbh->prepare("UPDATE apple SET user_id = ? WHERE apple_id = ?");
$sth->execute(array($user_id,apple_id));

$dbh->commit();

第二个交易将等到第一个交易提交。