0

我有一个 MySQL 数据库 (InnoDB),我正在开发用于跟踪我组织中的工单。有多个“站点”,每个站点的工单编号从 100 开始。

WorkorderID    SiteID    SiteWorkorderNum
     1           1            100
     2           1            101
     3           2            100

WorkorderID是自动增量字段。
SiteIDSiteWorkorderNum都设置为唯一约束。

每当要为特定站点插入新的工作订单时,应用程序都会检查登录者的 siteid 的 max(SiteWorkorderNum),并将该值返回到插入语句。我要避免的问题是,如果同一站点的两个用户都同时输入新的工作订单。

我有几个可能的解决方案,但我想看看是否有更好的方法,因为每个都有它的缺点,但我确信一个会比另一个更好,当然我对新想法持开放态度。

1)锁定表以保证在我们检索并插入我们的值之前没有其他用户检索 SiteWorkorderNum 值(但是假设我们每分钟有成千上万的用户试图输入工作订单,表锁不会减慢速度吗? )

2)不要锁定表,并检索下一个可用的 SiteWorkorderNum 并尝试插入到数据库中,如果我收到唯一约束错误,则捕获错误并重试,直到我成功。(这可能会释放表,但再次假设我们在同一个站点有数千个用户,多个数据库调用会有点低效吗?)

我是否对这些解决方案中的任何一个“可能”影响性能过于偏执?当然,我没有成千上万的用户,但我想在这个设计中应用最佳实践,以防我曾经从事过流量很大的项目。

4

1 回答 1

0

One option is to use transactions. If you do the SELECT MAX(SiteWorkorderNum) ... WHERE SiteID=... together with the resulting insert, then everything should work. The only problem is that your transactions might fail, which could be bad for the user experience.

The other scheme which I've used before is to have an allocation table with SiteId and NextWorkorderNum columns. Just do UPDATE SiteWorkorderAlloc SET @Num=NextWorkorderNum, NextWorkorderNum=NextWorkorderNum+1 WHERE SiteId=.... Then grab @Num to use as your workorder number in a subsequent insert. It works fine, the only minor drawback being that if there is a crash between getting the workorder number and the insert, that workorder number is lost (never used).

于 2012-06-09T06:14:14.207 回答