【问题标题】:PHP/MySQL PDO - getting a lastInsertId but table is missing the inserted row [closed]PHP / MySQL PDO - 获取lastInsertId但表缺少插入的行[关闭]
【发布时间】:2020-06-19 15:19:27
【问题描述】:

发生了非常奇怪的行为。我在 PHP 中有一个 API,它接受事务并执行插入到项目表中。该表有一个自动递增的 ID 字段。

当我执行 INSERT 时,我会检索我用来执行 LogActivity 条目的 lastInsertId。

有几个人在使用这个APP。我注意到在 LogActivity 表中,有一些带有 ID 的条目,但这些 ID 不在 ITEMS 表中。

我怎么可能检索 lastInsertId 但该 ID 不存在。就像执行了 INSERT,但随后又退出了??

这是并发问题吗?该表是 INNODB。我没有使用 TRANSACTION 或 LOCK 或 TRY/CATCH。

任何想法都将不胜感激。

//products.php
class Product{

    // database connection and table name
    private $conn;
    private $table_products = "table_products";
    private $table_productitems = "table_productitems";
    private $table_location = "warehouse_locations";

    // object properties
    public $id;
    public $productname;
    public $description;
    public $quantity;
    public $productid;
    public $customerid;
    public $thisid;
    public $thisitemid;
    public $productqty;
    public $newproductid;
    public $updateitemid;
    public $updateqty;
    public $type;
    public $result;
    public $insertitemid;
    public $insertqty;
    public $insertqrcode;
    public $searchStr;
    public $csproductname;
    public $cssku;
    public $csproductid;

    // constructor with $db as database connection
    public function __construct($db){
        $this->conn = $db;
    }

function addProductItemQRCode(){

    // query to insert record
    $query = "INSERT INTO table_productitems
              SET productid = :productid, quantity = :productqty, qrcode = :qrcode, modifydate = now()";

    // prepare query
    $stmt = $this->conn->prepare($query);

    // bind values
    $stmt->bindParam(':productid', $this->insertitemid);
    $stmt->bindParam(':productqty', $this->insertqty);
    $stmt->bindParam(':qrcode', $this->insertqrcode);

    // execute query
    if($stmt->execute()){
        $this->thisinsertid = $this->conn->lastInsertId();
    } else {
        $this->thisinsertid = '';
    }       

} 

// Activity function

function logActivity($customerid,$type,$result,$quantity,$userid){
    // query to insert record
    $query = "INSERT INTO api_activity 
                SET customerid=:customerid, type=:type, 
                    result=:result, quantity=:quantity, userid=:userid";

    // prepare query
    $stmt = $this->conn->prepare($query);

    // bind values
    $stmt->bindParam(':customerid', $customerid);
    $stmt->bindParam(':type', $type);
    $stmt->bindParam(':result', $result);
    $stmt->bindParam(':quantity', $quantity);
    $stmt->bindParam(':userid', $userid);

    // execute query
    if($stmt->execute()){
        return true;
    }
    return false;
}

// Addproductitems.php

// instantiate productitem insert object
$productiteminsert = new Product($db);
$productiteminsert->customerid = $post_customerid;
$productiteminsert->insertitemid = $productid->pid;
$productiteminsert->insertqty = $post_quantity;
$productiteminsert->insertqrcode = $post_qrcode;

// query products
$productiteminsert->addProductItemQRCode();

if($productiteminsert->thisinsertid!=null){

    $newitem = $productiteminsert->thisinsertid;

    // log the activity
    $product->logActivity($customerid=$productiteminsert->customerid, 
$type='add stock', $result=$productiteminsert->insertitemid.' ['.$newitem.'] ['.$productiteminsert->insertqrcode.']', 
$quantity=$productiteminsert->insertqty, $userid=$userid);
}



应用程序发布到 Addproductitems.php。

【问题讨论】:

  • 您是否以任何方式检查错误?
  • 能够看到导致这种奇怪活动的代码真的很有帮助
  • 另外,LogActivity tableitems 表有什么关系。架构的相关部分也很有用
  • 在日志表中添加外键约束,至少你会有适当的数据完整性。您还需要共享代码 - 也许您遗漏了什么
  • 当我对 ITEMS 表执行插入操作时,我得到了 lastInsertId 并将其传递给记录插入的函数。活动表只是将 ID 与其他一些信息一起放入结果字段中,因此不需要外键约束。

标签: php mysql


【解决方案1】:

首先,以下链接可以帮助您了解幕后发生的事情:https://stackoverflow.com/a/36573967/5922263 从该阅读中,请检查您的函数(我假设这些是各种函数,而不是方法,因为它们不包含诸如 public、private 等限定符)正在执行以下任何操作:

- creating some new connection by themselves; or
- doing multiple insertions at times; or 
- triggering some post-actions which modifies your 'global' $this->thisinsertid

这不是一个直接的解决方案,但它可能有助于为您指明正确的方向。

【讨论】:

  • 谢谢...我已添加到上面的代码中。 PRODUCT.PHP 对象文件包括 CLASS 和 PRIVATE 和 PUBLIC 声明。
  • 更新:我在 INSERT 周围添加了 TRY/CATCH 以及手动“BeginTransaction”和“commit”。今天早上也发生了同样的事情。记录了一个条目,但插入的项目不在表中。
猜你喜欢
  • 1970-01-01
  • 2013-03-11
  • 1970-01-01
  • 2012-09-16
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
  • 1970-01-01
  • 2012-06-07
相关资源
最近更新 更多