【问题标题】:MySQL 100% get last insert id LAST_INSERT_ID();MySQL 100% 获取最后插入 id LAST_INSERT_ID();
【发布时间】:2018-10-05 05:12:18
【问题描述】:

MySQL 具有获取最后插入的LAST_INSERT_ID(); 函数。

但这不安全:如果我运行一些查询然后得到 LAST_INSERT_ID() 并且在这两个查询之间执行另一个查询我会得到错误的 id。

这可能发生在使用同一连接的多个线程中,或者使用 pconnect(为多个用户保持连接)

是否有安全的方法来获取我想要 100% 的 ID?

谢谢

【问题讨论】:

  • 回答:除非您有来自同一连接的多个线程执行插入操作,否则您不必担心。
  • 是的,这是我的问题,我有多个具有相同连接的进程,在副本中没有多个线程的答案
  • 完成,谢谢,如果不好可以编辑
  • 我没有答案。我在想获得写锁可能会起作用,但写锁只会阻塞其他会话,而不是共享同一连接的多个线程。也许你应该尽量避免这种用例的发生。
  • 您需要在您的应用程序中实现互斥,以防止它们相互干扰。或者每个线程都应该使用自己的连接。

标签: mysql


【解决方案1】:

存储过程可能会有所帮助:

Create table test (id int AUTO_INCREMENT primary key, name varchar(50) )

存储过程为:

delimiter $$
DROP PROCEDURE IF EXISTS InserData$$
CREATE PROCEDURE InserData(IN _Name VARCHAR(50))
BEGIN
    START TRANSACTION;
    INSERT INTO test(name) VALUES (_Name);
    SELECT LAST_INSERT_ID() AS InsertID;
    COMMIT;
END

调用存储过程使用

 CALL InserData('TESTER')

试一试,因为我们有事务语句,但在多线程环境下无法保证价值。

链接Mysql thread safety of last_insert_id 说明它将基于每个连接 模型工作。

【讨论】:

    【解决方案2】:

    使用 SELECT Max(ID) FROM table 是否比使用 SELECT last_insert_id() 更安全,它们作为 2 个单独的查询运行? 根据您的问题,该表必须有一个主键。 所以你可以从 MAX(ID) 获取最后一条记录

    【讨论】:

    • 这并不能解决问题。我插入 id = 5 的行,在我得到 select max(id) 之前有人插入 id=6,我得到 id=6 的行,这将是不正确的
    • 你不应该回答问题
    猜你喜欢
    • 2011-06-01
    • 2017-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多