我正在尝试创建一个订购系统,并创建一个唯一的序列号来区分订单,它一直运行良好,直到有一次订单同时(差异只是几秒钟) ,大约10秒钟,然后唯一的序列号变得相同(序列号从db中的最后一个序列号开始增加) 我根据某种格式创建了id,并且必须每月重置一次,因此我无法使用uniqid()。
你们对此有什么想法吗?我读到了一些数据库锁定,但是当我尝试这个解决方案"Can we lock tables while executing a query in Zend-Db"时,它也没有用。
--- --- EDIT
格式为
项目编号 - 本月订单数量
这个月的订单数是从0001到9999开始的4位数 在9999之后,它将从A001 ... A999 B001 ...... ZZZZ再次开始
这是列
| order_id | varchar(17)| utf8_general_ci |没有| PRI |
我希望现在能让它变得更加清晰:)
谢谢!
答案 0 :(得分:2)
我主要考虑使用AUTO_INCREMENT
主键 - 有关详细信息,请参阅manual。
如果您无法使用InnoDB,则应该能够在Transaction中创建订单。在您的应用程序中,您可以检测是否存在重复项,并根据需要重新发出新ID。如果您的订单创建失败,使用事务将确保数据库中没有剩余数据。
基于附加信息进行编辑:
我添加AUTO_INCREMENT
主键并使用单独的" OrderName"所需格式的列。这应该允许您执行以下操作,例如:
UPDATE orders o
JOIN (
SELECT
year(o2.dte) y,
month(o2.dte) m,
min(o2.Order_ID) minid
FROM orders o2 GROUP BY y,m) AS t ON (t.m=month(dte) AND t.y=year(dte))
SET o.OrderName=CONCAT('p-n-',year(o.dte),"-",o.Order_ID-t.minid);
id
列为int PRIMARY KEY AUTO_INCREMENT
,并确保订单始终处于正确的顺序且不需要锁定。在此示例中,CONCAT将指定您的订单号格式。如果愿意,您可以在触发器中运行此UPDATE
,以确保立即填充OrderName。当然,如果你在触发器中运行它,你就不需要重新填充整个表格。
答案 1 :(得分:0)
似乎我们必须使用Serializable锁定事务。在事务完成之前,它将阻止从其他会话读取和写入。
请在这里查看
http://en.wikipedia.org/wiki/Isolation_%28database_systems%29