你好我有一个我在php脚本中填写的Mysql表。在此脚本中,我检查特定类型的条目数是否已达到最大值以通知客户。如果条目数少,我就让他在我的表中插入一个新条目。该表看起来像这样
--------------------
Date | Type
--------------------
Tuesday 13:00 | Car
检查的php脚本看起来像这样
<?php
$sql = $conn->prepare("SELECT count(*) FROM Table WHERE Date='Tuesday 13:00' AND Type='Car'");
$sql ->execute();
$sql_rows = $sql->fetchColumn();
if ($sql_rows > 20){
echo "All entries for this type has been filled please choose another to continue";
}else{
$insert = $conn->prepare("INSERT INTO Table VALUES('Tuesday 13:00', 'Car')");
$insert -> execute();
}
?>
我现在的问题是,如果100个人同时访问这个PHP脚本,那么php脚本将允许19个人自己插入“星期二13:00”,“汽车”进入数据库或更多,我怎么能防止这不会给客户带来不便吗?
答案 0 :(得分:1)
使用事务确保两个查询都使用表的相同快照。该事务将锁定表,以便其他人等待。将$conn->startTransaction()
放在第一个SELECT
查询之前,在查询中添加FOR UPDATE
子句,在$conn->commit()
之后添加INSERT
。
您必须使用InnoDB而不是MyISAM才能使交易有效。
<?php
$sql = $conn->prepare("SELECT count(*) FROM Table
WHERE Date='Tuesday 13:00' AND Type='Car'
FOR UPDATE");
$conn->startTransaction();
$sql ->execute();
$sql_rows = $sql->fetchColumn();
if ($sql_rows > 20){
echo "All entries for this type has been filled please choose another to continue";
}else{
$insert = $conn->prepare("INSERT INTO Table VALUES('Tuesday 13:00', 'Car')");
$insert -> execute();
}
$conn->commit();