这可能不是一个现实世界的问题,但更像是一个学习主题。
使用PHP,MySQL和PDO,我知道auto_increment和lastInsertId()。考虑主键没有auto_incerment属性,我们必须使用类似SELECT MAX(id) FROM table
的内容来检索最后一个id,手动递增,然后INSERT INTO table (id) VALUES (:lastIdPlusOne)
。将整个代码换成beginTransaction
和commit
。
这种方法安全吗?如果用户A和B同时加载此脚本,最终会发生什么?两笔交易都会失败?或者两者都会成功(例如,如果最后一个id为10,A将插入11而B将插入12)?
请注意,因为我是PHP& MySQL开发人员,因此我对这种情况下的MySQL行为更感兴趣。
答案 0 :(得分:0)
如果两者都获得相同的最大值,那么首先插入的那个将成功,而其他(s)将失败。
要在不使用auto_increment字段的情况下解决此问题,您可以在执行作业的插入之前使用触发器(new.id = max),即相同的逻辑,但是在触发器中,因此DB服务器是控制它的人。
在服务器发生故障的情况下,不确定在主 - 主复制环境中这是否100%安全。
答案 1 :(得分:0)
这是@ eggyal评论,我在这里引用:
您必须确保在第一个(选择)查询中使用locking read来获取MAX();然后它将阻塞,直到提交事务。但是,这是非常差的设计,不应在生产系统中使用。