两部分问题:
- 在我的CodeIgniter脚本中,我正在启动一个事务,然后插入一行,将insert_id()设置为php变量,使用新ID作为外键将更多行插入另一个表,然后我提交所有内容 .
所以我的问题是:如果在结束事务之前一切都没有提交,如果没有插入任何内容,mysql如何能够返回最后一个插入ID?我的脚本(几乎)完美地工作,新ID在后续查询中使用 .
(我说“差不多”因为,使用PDO mysql驱动程序,有时第一个应该返回insert_id()的插入是重复的 - 它被插入两次 . 任何想法为什么会这样?这与获取最后一个相关ID?如果使用mysqli或mysql驱动程序,它永远不会发生 . )
- 我首先写了没有事务的脚本,所以我有代码检查一路上的mysql错误,例如:
if(!$this->db->insert($table, $data)) {
//log message here
}
一旦我将所有mysql代码包装在事务中,这对mysql进程有何影响?它不会导致任何明显的错误(希望与上述问题无关),但它应该被删除吗?
谢谢 .
1 回答
回答你的第一个问题......
使用事务时,就您的连接而言,您的查询会正常执行 . 您可以选择提交,保存这些更改或回滚,还原所有更改 . 考虑以下伪代码:
// PHP
生成的随机数可以在提交之前读取,以确保它在保存之前适合所有人查看(例如提交和解锁行) .
如果PDO驱动程序不工作,请考虑使用mysqli驱动程序 . 如果这不是一个选项,您始终可以使用查询'select last_insert_id()作为id;'而不是$ this-> db-> insert_id()函数 .
要回答第二个问题,如果要插入或更新其他模型将要更新或读取的数据,请务必使用事务 . 例如,如果列“Number_remaining”设置为1,则可能发生以下问题 .
在相同情况下使用事务会产生以下结果:
您可能还想阅读transaction isolation levels .
注意死锁,在这种情况下会发生死锁:
最后,由于Person B可能已达到PHP的
max_execution_time
,因此当前查询将独立于PHP完成执行,但不会再收到任何查询 . 如果这是具有autocommit = 0的事务,则在切断与PHP服务器的连接时,查询将自动回滚 .