首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Mysql长连接断开,后续采集连接操作重复

Mysql长连接断开,后续采集连接操作重复
EN

Stack Overflow用户
提问于 2019-05-17 13:56:40
回答 2查看 39关注 0票数 0

当我获得到pdo的长连接时,执行事务插入操作,我手动断开连接或mysql自动断开连接一段时间,我重新获取连接执行事务将继续执行最后一个操作,导致数据插入到数据库中

mysql5.7

代码语言:javascript
复制
$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','111');
    $smtm->execute();
    throw  new \Exception('Manual exception throwing');
    $connection->commit();
}catch (\Throwable $e){
    echo ('Received exception information thrown:' . $e->getMessage());
    echo "\n";
    try{
        $connection->rollBack();
    }catch (\Throwable $e2){
        echo ('Exception fired by rollback:' . $e->getMessage());
        echo "\n";
    }
}

$connection = null;
echo 'connection Set to null, the current pdo link is broken';
echo "\n";
$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 "\n";
$connection->beginTransaction();
echo 'BeginTransaction to start a transaction';
echo "\n";
try{
    echo('New link transaction open status:'.($connection->inTransaction()?'yes':'no'));
    echo "\n";
    $smtm = $connection->prepare("INSERT INTO classic(class_name)VALUES(:name)");
    echo ('Current linked transaction status after connection->prepare() execution:'.($connection->inTransaction()?'yes':'no'));
    echo "\n";
    $smtm->bindValue(':name','222');
//    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 "\n";
    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 "\n";
    try{
        $connection->rollBack();
    }catch (\Throwable $e2){
        echo ('The exception triggered by the second rollback:' . $e2->getMessage());
        echo "\n";
    }
}

表格

代码语言:javascript
复制
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;

此代码会使数据库实际插入一段数据

EN

回答 2

Stack Overflow用户

发布于 2019-05-17 15:24:03

很奇怪,第二个事务是如何找到提交的方法的。将第二个连接名称更改为$connection1并运行。

代码语言:javascript
复制
<?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','111');
    $smtm->execute();
    throw  new \Exception('Manual exception throwing');
    $connection->commit();
}catch (\Exception $e){
    echo ('Received exception information thrown:' . $e->getMessage());
    echo "\n";
    try{
        $connection->rollBack();
    }catch (\Exception $e2){
        echo ('Exception fired by rollback:' . $e->getMessage());
        echo "\n";
    }
}

$connection = null;
echo 'connection Set to null, the current pdo link is broken';
echo "\n";
$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 "\n";
$connection1->beginTransaction();
echo 'BeginTransaction to start a transaction';
echo "\n";
try{
    echo('New link transaction open status:'.($connection1->inTransaction()?'yes':'no'));
    echo "\n";
    $smtm = $connection1->prepare("INSERT INTO classic(class_name)VALUES(:name)");
    echo ('Current linked transaction status after connection->prepare() execution:'.($connection1->inTransaction()?'yes':'no'));
    echo "\n";
    $smtm->bindValue(':name','222');
//    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 "\n";
    throw  new \Exception('The second transaction executes, throwing an exception manually');
    echo 'wowowowo'."\n";
    $connection1->commit();

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

Stack Overflow用户

发布于 2019-05-20 14:41:28

关闭连接时,应同时关闭connection对象和statement对象

$connection = null;$smtm = null;

我想这应该能解决你的问题。花了更多的时间来修复!

代码语言:javascript
复制
<?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','111');
    $smtm->execute();
    throw  new \Exception('Manual exception throwing');
    $connection->commit();
}catch (\Exception $e){
    echo ('Received exception information thrown:' . $e->getMessage());
    echo "\n";
    try{
        $connection->rollBack();
    }catch (\Exception $e2){
        echo ('Exception fired by rollback:' . $e->getMessage());
        echo "\n";
    }
}

$connection = null;
$smtm = null;

echo 'connection Set to null, the current pdo link is broken';
echo "\n";
$connection = new \PDO($dsn, 'root', 'infiniti', $pdoOptions);
echo 'Set to null and get the new link again to determine whether it is in the transaction:' .($connection->inTransaction()?'yes':'no');
echo "\n";
$connection->beginTransaction();
echo 'BeginTransaction to start a transaction';
echo "\n";
try{
    echo('New link transaction open status:'.($connection->inTransaction()?'yes':'no'));
    echo "\n";
    $smtm = $connection->prepare("INSERT INTO classic(class_name)VALUES(:name)");
    echo ('Current linked transaction status after connection->prepare() execution:'.($connection->inTransaction()?'yes':'no'));
    echo "\n";
    $smtm->bindValue(':name','222');
//    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 "\n";
    throw  new \Exception('The second transaction executes, throwing an exception manually');
    echo 'wowowowo'."\n";
    $connection->commit();

}catch (\Exception $e){
     echo ('Get new link exception catch:' . $e->getMessage());
    echo "\n";
    try{
        $connection->rollBack();
    }catch (\Exception $e2){
        echo ('The exception triggered by the second rollback:' . $e2->getMessage());
        echo "\n";
    }
}
?>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56180422

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档