如何避免在MySQL中插入重复条目?

如何避免在MySQL中插入重复条目?,mysql,Mysql,我的应用程序在注册新客户时生成ID号,然后将其插入客户表 生成ID的方法是读取最后一个ID号,然后将其递增1,然后将其插入表中 该应用程序将在拥有30多个用户的网络环境中使用,因此至少有两个用户有可能(概率?)在保存阶段读取相同的最后一个ID号,这意味着两个用户将获得相同的ID号 我也在使用事务。我需要一个在其他网站上找不到的逻辑解决方案 请回复说明,以便我能很好地理解。使用自动增量,您可以获得最后一个使用mysql\u insert\u id属性发布的id 如果由于某种原因无法实现,您可以创建

我的应用程序在注册新客户时生成ID号,然后将其插入客户表

生成ID的方法是读取最后一个ID号,然后将其递增1,然后将其插入表中

该应用程序将在拥有30多个用户的网络环境中使用,因此至少有两个用户有可能(概率?)在保存阶段读取相同的最后一个ID号,这意味着两个用户将获得相同的ID号

我也在使用事务。我需要一个在其他网站上找不到的逻辑解决方案


请回复说明,以便我能很好地理解。

使用自动增量,您可以获得最后一个使用mysql\u insert\u id属性发布的id

如果由于某种原因无法实现,您可以创建另一个表来保存最后使用的id,然后在事务中增加该id,然后将其用作插入表的键。必须有两个转换,否则你会有同样的问题,你现在。这可能会变得一团糟,而且需要额外的维护。(将下一个id表重置为零,此时相关表中仍有一些id,并且事情很快就会发生

在insert操作期间,除了在表上设置独占锁(甚至不推荐使用),您当前的解决方案就无法工作

好的,在保持模式不变的基础上扩展答案

伪代码中的选项1

StartTransaction
try
  NextId = GetNextId(...) 
  AddRecord(NextID...)
  commit transaction
catch Primary Key Violation
  rollback transaction
  Do the entire thing again
end
显然,您可能会在这里陷入无限循环,虽然不太可能,但也有可能,可能首先耗尽堆栈空间

如果成功地从队列中删除请求,您可以了解如何将请求排队,然后尝试处理它们

但让customerid成为一家汽车公司,整个问题就出现了。 它仍然是主键,您不必再计算出它需要什么,事实上,您不需要在insert语句中提供它,mysql将为您处理它

唯一需要记住的是,如果您需要自动创建的id,请在一个事务中请求它

因此,插入查询需要在表单中

Insert SomeTable(SomeColumns) Values(SomeValues)
Select mysql_insert_id

或者,如果多条语句妨碍将两条语句包装在一个start-stransaction-commit事务对中。

您是否知道
auto_increment
字段属性?它会创建一个自动递增的数字,该数字将由数据库管理,因此不可能重复。请确保您具有唯一的约束(或主键约束)在ID号列上。无论其他机制如何,该列都应该存在。有了该约束,即使两个客户端进程为“下一个ID”推断出相同的编号,也只有一个进程在插入时会成功。另一个进程必须检测到“唯一约束中的重复键”错误并重试。但是自动递增列这是更好的解决方案。此外,自动增量机制避免了可能影响
SELECT MAX(ID)的锁定问题+1
类型机制。其他数据库管理系统也有相同的机制-串行列、序列类型等。谢谢,但当我使用事务时,客户ID是主键,其中一个事务将正确回滚?!那么是否有方法检测回滚并为其/此处事务已回滚的用户重新排序save语句返回而不让最终用户知道发生了什么?回答扩展为解释。呃,是否重新排序save语句?