Php 正在将重复的ID发送到支付处理程序

Php 正在将重复的ID发送到支付处理程序,php,mysql,transactions,oscommerce,Php,Mysql,Transactions,Oscommerce,下面是一个场景。此表Orders有一个名为Orders\u id的自动增量列。该表使用InnoDB存储引擎。(这不是关于在Orders表中插入新记录,而是关于如何避免向处理器发送重复ID) 对于下一个订单,我计算下一个可用订单,如下所示 $new_order_id_query = "SHOW TABLE STATUS LIKE ORDERS"; $result = tep_db_query($new_order_id_query); $row = tep_db_fetch_array($resu

下面是一个场景。此表Orders有一个名为Orders\u id的自动增量列。该表使用InnoDB存储引擎。(这不是关于在Orders表中插入新记录,而是关于如何避免向处理器发送重复ID)

对于下一个订单,我计算下一个可用订单,如下所示

$new_order_id_query = "SHOW TABLE STATUS LIKE ORDERS";
$result = tep_db_query($new_order_id_query);
$row = tep_db_fetch_array($result);
$new_order_id = $row['Auto_increment'];
然后我收集其他信息,如姓名、地址、订购的物品。。。然后像这样发送给支付处理程序

102              44           xyz         44 Street
问题是有时,当同时有两个或多个订单时,我会向支付处理器发送两个具有相同订单id的订单

问题是如何确保我没有向支付处理程序发送重复的订单id

有人建议我使用last_insert_id(),这可能是对的,也可能是错的,但我不知道如何实现它


我读过关于锁定表的内容——这对于事务环境和InnoDB来说是个好主意吗?如果是,我如何实现它?

自动增量列通常不需要在代码中进行操作。插入用auto_定义的新记录列时,增量将自动递增

last_insert_id用于获取在连接上下文中分配给自动递增字段的值

我不建议在您的情况下锁定表,因为您在问题陈述中没有提供任何理由这样做。

如中所述:

  • 收集姓名、地址、订购的物品等

  • 将相关细节插入到
    订单
    表中,忽略提供
    id
    (MySQL将自动为您生成一个id,通过使用锁保证其唯一性)

  • 通过请求MySQL获取生成的
    id
    (实际的函数调用将取决于您的驱动程序)

  • 发送到您的付款处理程序


  • 您不需要计算下一个订单ID是什么。当您向该表中插入一行时,“自动增量”会自动为您生成下一个ID。这就是问题的关键所在

    您所需要做的就是运行一个insert,将所有其他信息放入表中,而不指定auto_increment字段的值

    "INSERT INTO Orders (cust_id, name, address) VALUES (55, 'me', 'My House')"
    
    如果您想知道刚才插入的行的订单ID是什么,只需对查询结果调用last_insert_ID()。我不知道什么是
    tep\u db
    ,因为我没有使用过它,但我认为您需要函数
    tep\u db\u insert\u id()

    我正在计算ID,因为我需要在实际插入之前将其发送给支付处理器

    您提到的所有技术都要求您打开一个数据库连接,并在不同的HTTP请求之间保持它的打开状态(同时防止其他脚本实例使用它),这样就可以从单个数据库会话中获益。没有可靠的方法可以做到这一点

    我已经很久没有与osCommerce合作了(我很惊讶它仍然存在:),但您基本上有两种可能性:

    • 以通常的方式插入实际订单,但将其标记为待定
    • 在另一个表中插入预订单(可能由您设计)

    老实说,我认为在重定向到支付网关之前,您需要保存订单。如果您信任会话数据,您迟早会失去订单;而且您将丢失已付款的订单,这更糟糕。

    将数据插入表中,并显示挂起状态,然后在处理完后更新它。这样,您的订单总是与实际条目相关。我有点困惑,如果是自动递增的,为什么要计算id?您是否先将其添加到订单表,然后再将其发送到付款处理程序?如果是,那么使用last_insert_id()。这是怎么回事?a) 您以前从未使用过AUTO_INCREMENT,也不知道如何b)您想为将来的插入保留订单ID吗?c) 其他注意事项:last_insert_id()将只提供该脚本实例的插入id。没有交叉,完全安全。@alvarog.Vicario我想说a)和b)都可以,我理解,但是如果订单被支付处理者拒绝了怎么办?那就意味着它不应该在orders表中。但是通过这些步骤,订单在评估之前就已经在订单表中了。@ManishPradhan:然后在
    Orders
    表中将其标记为拒绝,或者将其删除(在您的业务逻辑中视情况而定)。这实际上是有意义的,但是出于好奇,我有没有办法在任何插入之前获得下一个ID?@ManishPradhan:你可以锁定表,这样就没有其他线程可以插入,那么你就会知道下一个ID将是你的——但是(出于明显的性能原因)这通常是一个非常糟糕的主意。@eggycal我想告诉你,问题不是关于插入,我有自动递增,以确保我没有重复的行。问题是我是否可以在不允许并发线程读取相同ID的情况下读取下一个可用ID。因为现在两个线程正在读取相同的下一个ID。但我没有执行insert语句。那就在最后。我只需要在开始时的下一个值发送给处理器。
    "INSERT INTO Orders (cust_id, name, address) VALUES (55, 'me', 'My House')"