php - 多个连接上的事务,当一个事务执行时数据完整性失败

标签 php mysql mysqli transactions data-integrity

我正在尝试在以下场景中为小型应用程序使用 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/

相关文章:

php - 升级到 PHP 7 后 session 不起作用

python - 加快单独更新项目的速度

php - 如何解决 mysqli_fetch_assoc 错误?

php - 意外的 mysql 错误说必须是 mysqli_result 的实例?

php - 无法使用 AFHTTPRequestOperation post 方法将希伯来文文本插入 mysql 数据库

mysql - 是否可以通过 ssl 将 typeorm 连接到 sql gcloud 的实例?

php - mysqli_stmt_close() 期望参数 1 是 mysqli_stmt, bool 值

javascript - 通过 Ajax PHP 从 Javascript onClick 更新数据库

php - MySQL 多表链接

php - 表锁失败