原子地建立记录之间的关系

时间:2014-05-17 07:32:15

标签: sql atomic consistency

我正在开发一个提供独特数字产品(例如40位代码)的电子商务网站。这些数字产品作为行存储在stock表中。下订单时,应为订单分配一个独特的数字产品

目前,我正在选择最老的产品(以先进先出的方式),做一些业务逻辑(向客户发送电子邮件等)并从库存表中删除记录。问题是此操作是非原子。例如。如果同时下达两个订单,则选择相同的代码,通过电子邮件发送给客户并删除(尽管第二个删除将失败,当然)。这使数据库处于不一致状态(从业务角度来看),因为同一个唯一数字产品被分配给两个订单。

如何以一致/原子的方式在表格stock中的数字产品与表格order中的订单之间建立链接?

PS。我目前正在使用MySQL(MyISAM),但我不太喜欢缺乏参照完整性。我打算在不久的将来转移到InnoDB或PostgreSQL。因此,我更喜欢与技术无关的答案。

1 个答案:

答案 0 :(得分:0)

向Stock表添加一列。称之为Allocated或其他。其值为0(未分配)或1(已分配)。 0是默认值。从Stock读取一行以添加到客户的订单后,您将拥有主键,我假设。那你

update Stock
set Allocated = 1
where Stock.PrimaryKey = <the value you just read>
and Stock.Allocated = 0;

除非您设置了一些病理隔离级别,否则根据定义,这个语句原子。

如果失败,其他人就在该库存项目上调用了“dibs”。循环回“读取最旧的库存项目”步骤。当然,您只想阅读项目where Allocated = 0。根据需要经常重复,或者用完库存物品。

如果您的流程在后续步骤中失败,您可能最终会收到一些孤立的库存商品,例如Allocated = 1但未发送任何电子邮件。

你最好围绕所有这些步骤进行交易,因为你希望它们都能成功或全部回滚。