我正在尝试在以下场景中为小型应用程序使用 OOPS 代码开发基于事务的 PHP-MYSqli:
PHP 5.6.x 用于服务器和 PHP 桌面版本 phpdesktop-chrome-57.0-rc-php-7.1.3,因此应用程序将在 5.6.x 上运行和 7.x 版本的 PHP。
Multiple people can access the same php application simultaneously. This means that every user will have an independent connection available to access the application because I have included a connection on the top of every page through files inclusion. What I want is that when one user presses the submit button, all the tables inside a particular transaction should get locked in read and write mode and none of them should be accessible by any of the users on the same or any other connection. Thus, I want 100% data integrity.
我编写了以下两个文件:
p1.php
<?php
ini_set('max_execution_time', 500);
$mysqli = new mysqli("localhost", "root", "", "jag_db");
if ($mysqli->connect_errno) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
}
if(isset($_POST['submit']))
{
$mysqli->autocommit(FALSE);
//$mysqli->begin_transaction(MYSQLI_TRANS_START_READ_WRITE);
$i=0;
$val2="Kurukshetra";
for($i=100;$i<=50000;$i++)
{
$stmt=$mysqli->prepare("INSERT INTO transtest (roll,city) VALUES(?,?)");
$stmt->bind_param('ss', $i, $val2);
if(!$stmt->execute())
{
$mysqli->rollback();
exit;
}
}
$sql20=$mysqli->prepare("SELECT * FROM transtest");
$sql20->execute();
$result20=$sql20->get_result();
if($result20->num_rows>0)
{
while($rows20=$result20->fetch_object())
{
$sno=$rows20->sno;
$stmt=$mysqli->prepare("UPDATE transtest SET city=? WHERE sno=?");
if($sno%2==0)
$city="Ambala";
else
$city="Kaithal";
$stmt->bind_param('ss', $city, $sno);
if(!$stmt->execute())
{
$mysqli->rollback();
exit;
}
}
}
else
{
$mysqli->rollback();
exit;
}
$stmt->close();
$mysqli->commit();
$mysqli->autocommit(TRUE);
}
$mysqli->close();
?>
<form method="post">
<button type="submit" name="submit"/>GO</button>
</form>
p2.php
<?php
ini_set('max_execution_time', 500);
$mysqli = new mysqli("localhost", "root", "", "jag_db");
if ($mysqli->connect_errno) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
}
if(isset($_POST['submit']))
{
$mysqli->autocommit(FALSE);
//$mysqli->begin_transaction(MYSQLI_TRANS_START_READ_WRITE);
$i=5001;
$j="Chandigarh";
$stmt=$mysqli->prepare("INSERT INTO transtest (roll,city) VALUES(?,?)");
$stmt->bind_param('ss', $i, $j);
if(!$stmt->execute())
{
$mysqli->rollback();
exit;
}
$sql20=$mysqli->prepare("SELECT * FROM transtest");
$sql20->execute();
$result20=$sql20->get_result();
if($result20->num_rows>0)
{
while($rows20=$result20->fetch_object())
{
echo $rows20->sno . " ---- " . $rows20->roll . " ---- " . $rows20->city . "<br>";
}
}
else
{
$mysqli->rollback();
exit;
}
$sql20->close();
$mysqli->commit();
$mysqli->autocommit(TRUE);
}
$mysqli->close();
?>
<form method="post">
<button type="submit" name="submit"/>GO</button>
</form>
首先,我开始执行 p1.php,然后立即开始单击 p2.php 另一个浏览器选项卡的“执行”按钮。 以下是 p2.php 时的结果:
p1.php仍在执行
Image: p1.php is still executing
当 p1.php 完成执行时
Image: when p1.php has finished executing
很高兴看到最后我得到了准确的结果,但很糟糕的是,即使执行一个事务,另一个用户也得到了错误的输出。当 p1.php 执行时,第二个用户不应该看到任何内容。
Note: $mysqli->begin_transaction(MYSQLI_TRANS_START_READ_WRITE); doesnt work in my current version of php. It says Warning: mysqli::begin_transaction(): This server version doesn't support 'READ WRITE' and 'READ ONLY'. Minimum 5.6.5 is required
如何解决这个问题?
最佳答案
对于Mysql,当你在代码中编写的任何操作被执行时,都会自动锁定表,所以你是安全的。
关于php - 多个连接上的事务,当一个事务执行时数据完整性失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51595417/