繁体   English   中英

SELECT LAST_INSERT_ID()间歇返回0

[英]SELECT LAST_INSERT_ID() intermittently returns 0

我搜索了许多类似的问题,尽管找不到间歇性返回0的问题

****编辑*****

从那以后,我尝试使用只有两列的新表进行测试,将问题减少到返回零的50次中的1分之一。

我也刚刚能够在付费托管服务器上进行测试,而我无法复制我的问题

我认为该问题仅针对该虚拟主机。

问题:

当尝试在每个连接的基础上检索最后插入的ID时,大约十分之四的次数返回0。

Localhost,一切正常,没有问题。 仅当我的网站托管在服务器上时,才会出现此问题。

SELECT LAST_INSERT_ID() intermittently returns 0

$PDOconnection->lastInsertId(); Always returns correct ID

我需要在每个连接基础上可靠地获取最后插入的ID,因为在数据库中创建采购订单时,这对于我的网站的结帐流程至关重要。

笔记:

  • ID是自动递增的
  • sql插入始终可以正常工作,并且数据库显示一个新条目。
  • 切换PHP版本不能解决问题
  • 我正在使用的网络托管服务是我用于实时测试的免费托管服务
  • 页面加载时间始终相似(以下代码为500-750ms)

我剥离了整个代码(如下所示)以进行简单测试。 问题仍然存在

我似乎无法锻炼我的问题所在。

include_once "php/config.php";

$cookie_id = 0;

// Time of checkout
$time = gmdate("d/m/Y h:i:s");

// Create new purchase order
$sql_insert = "INSERT INTO user_purchases (cart_id, timestamp) VALUES (:cookie_id, :time)";

$stmt_insert = $PDOconnection->prepare($sql_insert);
$stmt_insert->bindParam(':cookie_id', $cookie_id, PDO::PARAM_STR);
$stmt_insert->bindParam(':time', $time, PDO::PARAM_STR);
$stmt_insert->execute();

$checkout_id_0 = $PDOconnection->lastInsertId();

// Get the primary key id of the last inserted item on per-connection basis
$sql_last_id = "SELECT LAST_INSERT_ID()";
$stmt_last_id = $PDOconnection->prepare($sql_last_id);
$stmt_last_id->execute();
$r_last_id = $stmt_last_id->fetch(PDO::FETCH_ASSOC);

$checkout_id_1 = $r_last_id['LAST_INSERT_ID()'];

echo $checkout_id_0 . " " . $checkout_id_1;  // I echoed out to observe results

连续10个查询的结果的真实示例(只需刷新页面即可)。 我并排地回应了结果。

checkout_id_0      $checkout_id_1  <---SELECT LAST_INSERT_ID()

      16                16
      17                17
      18                0        // Returned 0
      19                19
      20                0        // Returned 0
      21                0        // Returned 0
      22                22
      23                23
      24                23       // Returned previous ID (happens 1/30 tries)
      25                25

连接配置:

$PDOconnection = new PDO("mysql:host=$servername;dbname=$dbname;charset=utf8", $sql_username, $sql_password);

// Set PDO error mode to exception
$PDOconnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// Set PDO Attribute to force native prepared statements
$PDOconnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

您是否尝试过激活持久连接? 请参见连接和连接管理持久数据库连接 也许远程服务器的MySQL设置太短了wait_timeoutinteractive_timeout ...

持久连接不会在脚本结尾处关闭,而是在另一个脚本使用相同凭据请求连接时被缓存并重新使用。 持久连接缓存使您避免每次脚本需要与数据库进行通信时建立新连接的开销,从而加快了Web应用程序的速度。

另请注意:

如果希望使用持久连接,则必须在传递给PDO构造函数的驱动程序选项数组中设置PDO :: ATTR_PERSISTENT。 如果在实例化对象后使用PDO :: setAttribute()设置此属性,则驱动程序将不使用持久连接。

所以:

$PDOconnection = new PDO(
    "mysql:host=$servername;dbname=$dbname;charset=utf8"
    , $sql_username
    , $sql_password
    , array(
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_EMULATE_PREPARES => false,
        PDO::ATTR_PERSISTENT => true,
    )
);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM