如果你使用的是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(現有行)值(請參閱Trigger syntax)。我在這個例子中所做的只是在服務器上維護一個單獨的計數器@vcount。要將此值初始化爲當前ID的任何值,只需執行「SET @vcount = 42;」
Luhn算法。您必須將其作爲SQL函數來實現。 Here's SQL中的一個Luhn驗證器,您可以從中剔除。或者,您可以使用本機MySQL函數(如MD5)進行散列/校驗和(如果需要短代碼代碼,則只使用前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 ;
然後,在你的插入,你會在查詢放只是「64352」,因爲你已經建議。觸發器會附加其餘的。個人而言,除非你或其他人可以更好地解決autoincrement/@ vcount問題,否則我仍然更願意進行MySQL事務處理,這將比保持所有原子操作並將所有應用程序代碼保存在PHP中做得更好。
概率應該提到我使用的代碼點火器... – Hailwood 2011-05-12 01:00:53
我一直在尋找MySQL的觸發器,我相信這是可行的。我會用一些半個示例代碼更新我的答案。或者,您仍然可以通過代碼點火器來完成交易。將應用程序代碼嵌入到觸發器/存儲過程中有其優點和缺點。 – joelhardi 2011-05-12 01:17:20
OK,我的觸發結束了更多比我預想的完全成熟。添加一個Luhn函數,它應該可以工作。在我的例子盧恩()將返回校驗值作爲一個字符串,所以如果你有這回你只需要包裝科協返回值(AS CHAR)將int。祝你好運! – joelhardi 2011-05-12 01:53:10