Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何获取mysql';s的上次插入ID是否用于事务+;交易问题_Mysql_Codeigniter_Transactions_Pdo - Fatal编程技术网

如何获取mysql';s的上次插入ID是否用于事务+;交易问题

如何获取mysql';s的上次插入ID是否用于事务+;交易问题,mysql,codeigniter,transactions,pdo,Mysql,Codeigniter,Transactions,Pdo,由两部分组成的问题: 在我的CodeIgniter脚本中,我启动一个事务,然后插入一行,将insert_id()设置为一个php变量,使用新id作为外键将更多行插入另一个表,然后提交所有内容 所以我的问题是:如果在结束事务之前没有提交所有内容,那么如果没有插入任何内容,mysql如何能够返回最后一个插入ID?我的脚本工作(几乎)完美,在后续查询中使用新ID (我之所以说“几乎”是因为,使用PDO mysql驱动程序,有时应该返回insert_id()的第一个insert被复制——它被插入了两次。

由两部分组成的问题:

  • 在我的CodeIgniter脚本中,我启动一个事务,然后插入一行,将insert_id()设置为一个php变量,使用新id作为外键将更多行插入另一个表,然后提交所有内容

    所以我的问题是:如果在结束事务之前没有提交所有内容,那么如果没有插入任何内容,mysql如何能够返回最后一个插入ID?我的脚本工作(几乎)完美,在后续查询中使用新ID

    (我之所以说“几乎”是因为,使用PDO mysql驱动程序,有时应该返回insert_id()的第一个insert被复制——它被插入了两次。知道为什么会这样吗?这与获取最后一个id有关吗?如果使用mysqli或mysql驱动程序,永远不会发生这种情况。)

  • 我首先编写的脚本没有事务,因此我有代码在编写过程中检查mysql错误,例如:

    if(!$this->db->insert($table, $data)) {
        //log message here
    }
    
    一旦我将所有mysql代码包装到一个事务中,这将如何影响mysql进程?它不会导致任何可见错误(希望与上述问题无关),但是否应该将其删除


  • 谢谢。

    要回答您的第一个问题

    在使用事务时,就连接而言,查询是正常执行的。您可以选择提交、保存这些更改,或者回滚、还原所有更改。考虑下面的伪代码:

    insert into number(Random_number) values (rand()); 
    select Random_number from number where Number_id=Last_insert_id();
    
    //php

    在相同情况下使用事务将产生以下结果:

    人员A启动事务
    人员A从中读取“1” 剩余人数_
    (如果使用该行,则该行现在被锁定)
    人员B 尝试读取剩余的数字\u-强制等待
    人员A获胜 $1000
    人员A将1更新为0
    人员A提交
    人员B 阅读0
    B个人没有赢得1000美元
    B个人哭泣

    你也可能想好好读一读

    注意死锁,在这种情况下可能会发生:

    人员A读取第1行(
    select…for update

    人员B读取第1行 2(
    为更新选择…)
    人员A尝试读取第2行, 强制等待
    人员B尝试读取第1行,强制等待
    人员A到达(默认为50秒)并且 断开连接的
    人员B读取第1行并正常继续


    最后,由于人员B可能已达到PHP的
    max_execution_time
    ,因此当前查询将独立于PHP完成执行,但不会收到进一步的查询。如果这是一个autocommit=0的事务,当与PHP服务器的连接断开时,查询将自动回滚。

    谢谢您的回答!为了确保我理解正确,您的意思是说,如果我将所有mysql查询包装在一个事务中,并且您在上面编写的场景发生(两个用户同时访问一个“获胜”页面),那么它将只对一个人进行处理?我需要在事务开始时检查剩余的
    number_
    是否等于1,对吗?对。对于我给出的示例,您还需要确保隔离级别设置为可序列化,或者使用“select For update”来锁定select上的行。Update、delete和insert语句也根据隔离级别具有不同的锁定行为。在每个查询中使用事务可能会导致死锁,因此在数据最新和准确至关重要时使用它们。我已经更新了我的答案,添加了一个启用事务的示例。非常感谢,这是一个很好的解释!我不知道你提到的那些mysql选项。如果你不介意的话,我还有几个问题:1。我在mysql文档中查找了
    serializable
    ,它显示它在共享模式下设置了
    锁。这实际上并不妨碍选择行。我想
    选择。。。对于更新,是否应使用
    ,是否正确(它会阻止读取)?2.在什么情况下使用事务会出现死锁?为什么后续事务不干脆等待轮到它们呢?在共享模式下使用正确的、可序列化的锁,因此在本例中,您必须使用
    select。。。对于更新
    ,我将更正我的答案以反映这一点。非常感谢您对所有内容的清晰解释!我希望我能投你两次票。
    if($num < 1)
       $this->db->query('rollback;'); // This number is too depressing.
    else
       $this->db->query('commit;'); // This number is just right.
    
    Person A reads 1
    Person B reads 1
    Person A wins $1000!
    Person A updates 1 to be 0
    Person B wins $1000!
    Person B updates 0 to be 0