如果您使用 InnoDB,一个简单的解决方法就是使用您现有的代码并将其包装在 MySQL 事务中。即在伪代码中:
mysql_query("START TRANSACTION");
# get next autoincrement value into: $next
# do your INSERT query
# get the actual last inserted ID into: $actual
if ($next === $actual) {
mysql_query("COMMIT");
} else {
mysql_query("ROLLBACK");
# and raise an Exception or return an error
}
编辑/添加:
既然您提到了触发器,我对此进行了研究并相信它是可行的。几个问题。
从触发器访问“下一个自动增量 ID”......我不知道这样做的“好”方法。在 INSERT 查询中,您只能访问 NEW 而不是 OLD(现有行)值(请参阅触发器语法)。我在示例中所做的只是在服务器上维护一个单独的计数器@vcount。要将此值初始化为当前的 ID,您只需执行“SET @vcount = 42;”
卢恩算法。您必须将其实现为 SQL 函数。这是您可以从中借鉴的 SQL 中的 Luhn 验证器。或者,您可以使用诸如 MD5 之类的本机 MySQL 函数进行哈希/校验和(如果您需要简短的凭证代码,则仅使用前 X 字符)。在任何情况下,您都需要创建一个散列函数......我将在下面使用“Luhn”。
无论如何,这是触发器的样子:
delimiter //
CREATE TRIGGER make_voucher_code BEFORE INSERT ON vouchers
FOR EACH ROW
BEGIN
SET @vcount = @vcount + 1;
SET NEW.voucher = CONCAT(
NEW.voucher,
CAST(@vcount AS CHAR),
Luhn(CONCAT(NEW.voucher, CAST(@vcount AS CHAR))));
END;
//
delimeter ;
然后,按照您的建议,在您的 INSERT 中,您只需在查询中输入“64352”。触发器将附加其余部分。
就个人而言,除非您或其他人可以更好地解决 autoincrement/@vcount 问题,否则我仍然更喜欢执行 MySQL 事务,这将比保持一切原子性并将所有应用程序代码保留在 PHP 中做得更好。