SELECT LAST_INSERT_ID()间歇性地返回0

时间:2017-10-14 11:15:58

标签: php mysql pdo

我搜索了很多类似的问题,虽然我找不到任何间歇性返回0

****编辑*****

此后我尝试使用只有两列的新表进行测试,将问题减少到50左右,返回零。

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

我认为这个问题特定于该网络主机。

问题:

当尝试在每个连接的基础上检索最后一个插入的ID时,大约有4次我得到0返回给我。

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

vector::emplace_back()

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

备注:

  • ID自动递增
  • sql插件始终正常,数据库显示新条目。
  • 切换PHP版本无法解决问题
  • 网络托管我正在使用的是一个免费托管服务,我正在使用直播 测试目的
  • 页面加载时间总是相似的(下面的代码为500 - 750毫秒)

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

我似乎无法解决问题所在。

SELECT LAST_INSERT_ID() intermittently returns 0

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

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

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

连接配置:

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

1 个答案:

答案 0 :(得分:0)

您是否尝试过激活持久连接?请参阅Connections and Connection managementPersistent Database Connections。也许远程服务器的MySQL设置太短 - wait_timeoutinteractive_timeout ...

  

脚本末尾没有关闭持久连接,但是   当另一个脚本使用请求连接时缓存并重新使用   相同的凭据。持久连接缓存允许您   避免每次a建立新连接的开销   脚本需要与数据库通信,从而产生更快的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,
    )
);