Mysql длинное соединение отключено, повторная операция подключения соединения повторяется

Когда я получаю длинное соединение с pdo, выполняю операцию вставки транзакции, я вручную отключаюсь или mysql автоматически отключается на некоторое время, я повторно получаю транзакцию выполнения соединения, которая продолжит выполнять последнюю операцию, вызывая вставку данных в база данных

mysql5.7

$pdoOptions       = [
    PDO::ATTR_TIMEOUT    => 30,
    PDO::ATTR_PERSISTENT => true,
];
$dsn              = "mysql:host=mysql;port=3306;dbname=test;charset=utf8";
$connection = new PDO($dsn, 'root', 'root', $pdoOptions);
try{
    $connection->beginTransaction();
    $smtm = $connection->prepare("INSERT INTO classic(class_name)VALUES(:name)");
    $smtm->bindValue(':name',飇');
    $smtm->execute();
    throw  new Exception('Manual exception throwing');
    $connection->commit();
}catch (Throwable $e){
    echo ('Received exception information thrown:' . $e->getMessage());
    echo "
";
    try{
        $connection->rollBack();
    }catch (Throwable $e2){
        echo ('Exception fired by rollback:' . $e->getMessage());
        echo "
";
    }
}

$connection = null;
echo 'connection Set to null, the current pdo link is broken'
echo "
";
$connection = new PDO($dsn, 'root', 'root', $pdoOptions);
echo 'Set to null and get the new link again to determine whether it is in the transaction:' .($connection->inTransaction()?'是':'否');
echo "
";
$connection->beginTransaction();
echo 'BeginTransaction to start a transaction'
echo "
";
try{
    echo('New link transaction open status:'.($connection->inTransaction()?'yes':'no'));
    echo "
";
    $smtm = $connection->prepare("INSERT INTO classic(class_name)VALUES(:name)");
    echo ('Current linked transaction status after connection->prepare() execution:'.($connection->inTransaction()?'yes':'no'));
    echo "
";
    $smtm->bindValue(':name',餶');
//    echo $smtm->queryString;
    $smtm->execute();
    echo 'After the new link is obtained, an exception is thrown and the second execution fails to roll it back'
    echo "
";
    throw  new Exception('The second transaction executes, throwing an exception manually');
    $connection->commit();
}catch (Throwable $e){
     echo ('Get new link exception catch:' . $e->getMessage());
    echo "
";
    try{
        $connection->rollBack();
    }catch (Throwable $e2){
        echo ('The exception triggered by the second rollback:' . $e2->getMessage());
        echo "
";
    }
}

Таблица

CREATE TABLE `classic` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `class_name` VARCHAR(50) NULL DEFAULT NULL,
    PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1;

Этот код заставляет базу данных фактически вставить часть данных

Всего 1 ответ


очень странно, вторая транзакция как-то находит способ совершить. измените имя второго соединения на $ connection1 и запустите.

<?php
namespace app;
ini_set('display_errors', 1);
$pdoOptions       = [
    PDO::ATTR_TIMEOUT    => 30,
    PDO::ATTR_PERSISTENT => true,
];
$dsn              = "mysql:host=localhost;port=3306;dbname=test;charset=utf8";
$connection = new PDO($dsn, 'root', 'infiniti', $pdoOptions);
try{
    $connection->beginTransaction();
    $smtm = $connection->prepare("INSERT INTO classic(class_name)VALUES(:name)");
    $smtm->bindValue(':name',飇');
    $smtm->execute();
    throw  new Exception('Manual exception throwing');
    $connection->commit();
}catch (Exception $e){
    echo ('Received exception information thrown:' . $e->getMessage());
    echo "
";
    try{
        $connection->rollBack();
    }catch (Exception $e2){
        echo ('Exception fired by rollback:' . $e->getMessage());
        echo "
";
    }
}

$connection = null;
echo 'connection Set to null, the current pdo link is broken'
echo "
";
$connection1 = new PDO($dsn, 'root', 'infiniti', $pdoOptions);
echo 'Set to null and get the new link again to determine whether it is in the transaction:' .($connection1->inTransaction()?'yes':'no');
echo "
";
$connection1->beginTransaction();
echo 'BeginTransaction to start a transaction'
echo "
";
try{
    echo('New link transaction open status:'.($connection1->inTransaction()?'yes':'no'));
    echo "
";
    $smtm = $connection1->prepare("INSERT INTO classic(class_name)VALUES(:name)");
    echo ('Current linked transaction status after connection->prepare() execution:'.($connection1->inTransaction()?'yes':'no'));
    echo "
";
    $smtm->bindValue(':name',餶');
//    echo $smtm->queryString;
    $smtm->execute();
    echo 'After the new link is obtained, an exception is thrown and the second execution fails to roll it back'
    echo "
";
    throw  new Exception('The second transaction executes, throwing an exception manually');
    echo 'wowowowo'."
";
    $connection1->commit();

}catch (Exception $e){
     echo ('Get new link exception catch:' . $e->getMessage());
    echo "
";
    try{
        $connection1->rollBack();
    }catch (Exception $e2){
        echo ('The exception triggered by the second rollback:' . $e2->getMessage());
        echo "
";
    }
}
?>

Есть идеи?

10000