【发布时间】:2013-08-29 08:37:38
【问题描述】:
我正在尝试创建一个类似 fb 的按钮功能(不是 facebook api)。 我的网站上有两个按钮:喜欢和不喜欢。 数据库将保存总共有多少喜欢和不喜欢。
这是数据库表:
id |post_id |like_count
40 | 20 | 0
用户点击赞按钮时的代码:
$id = 40;
$conn->autocommit(FALSE);
$conn->query("BEGIN;");
//lock the row to prevent race condition
$sql = "SELECT like_count FROM post_like WHERE id = ? LIMIT 1 FOR UPDATE";
$stmt = $conn->prepare($sql);
$stmt->bind_param('i', $id);
$stmt->execute();
$stmt->close();
//update the table
$sql = "UPDATE post_like SET like_count = like_count + 1 WHERE id = ? LIMIT 1";
$stmt = $conn->prepare($sql);
$stmt->bind_param('i', $id);
$stmt->execute();
$stmt->close();
$conn->commit();
$conn->autocommit(TRUE);
$conn->close();
//when success, display unlike button to user throught AJAX
以及用户点击不同按钮时的代码:
$id = 40;
$conn->autocommit(FALSE);
$conn->query("BEGIN;");
//lock the row to prevent race condition
$sql = "SELECT like_count FROM post_like WHERE id = ? LIMIT 1 FOR UPDATE";
$stmt = $conn->prepare($sql);
$stmt->bind_param('i', $id);
$stmt->execute();
$stmt->close();
//update the table
$sql = "UPDATE post_like SET like_count = like_count - 1 WHERE id = ? LIMIT 1";
$stmt = $conn->prepare($sql);
$stmt->bind_param('i', $id);
$stmt->execute();
$stmt->close();
$conn->commit();
$conn->autocommit(TRUE);
$conn->close();
//when success, display like button to user throught AJAX
这就是问题...
like_count 的数量从 0 开始。
理论上,如果只有一个人点击按钮,like_count不会超过1也不小于0。
(点赞按钮->->锁定行->like_count+1->释放行->显示不一样按钮)
(点击不像按钮->锁定行->like_count-1->释放行->显示像按钮)
当我缓慢单击按钮时,我可以正确地完成这项工作,但是,当我继续快速单击按钮时,like_count 的数量可能会超过 2,有时可能是负数。
我不知道我做错了什么。请帮忙!
【问题讨论】:
-
最后一次更新,为什么执行在bind_param之前?
-
让我问你一个问题。这里的比赛条件有什么问题?
标签: php transactions mysqli prepared-statement table-locking