首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >mysql插入竞争条件

问mysql插入竞争条件
EN

Stack Overflow用户
提问于 2008-11-05 10:40:51
回答 8查看 14.9K关注 0票数 12

如何在MySQL中停止比赛条件?当前的问题是由一个简单的算法引起的:

  1. 从表中选择一行
  2. 如果它不存在,插入它

然后要么得到一个重复的行,要么通过唯一/主键防止它发生错误。

现在,我通常认为事务在这里有所帮助,但是由于行不存在,事务实际上没有帮助(还是我遗漏了什么?)

锁表听起来有点过火,特别是如果表每秒更新多次的话。

我能想到的唯一其他解决方案是针对每个不同id的GET_LOCK(),但是没有更好的方法吗?这里也没有可伸缩性问题吗?而且,对每个表都这样做听起来有点不自然,因为在我看来,这在高并发数据库中是一个非常常见的问题。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2008-11-05 10:44:24

你想要的是锁表

或者,如果这似乎太过了,那么检查行是否实际插入的插入忽略如何?

如果使用“忽略”关键字,则执行INSERT语句时发生的错误将被视为警告。

票数 10
EN

Stack Overflow用户

发布于 2008-11-05 10:45:23

在我看来,您应该在id列上有一个唯一的索引,因此重复插入将触发错误,而不是再次盲目地接受。

这可以通过将id定义为主键或单独使用唯一索引来完成。

我认为您需要问的第一个问题是,为什么有许多线程在执行完全相同的工作?他们为什么要插入完全相同的一行?

在得到答案之后,我认为忽略错误将是最有效的解决方案,但是度量这两种方法(GET_LOCK v/s忽略错误)并亲自查看。

据我所知,没有别的办法了。为什么要避免错误?当发生另一种类型的错误时,您仍然必须为这种情况编写代码。

正如staticsan说的那样,事务确实有帮助,但是,由于它们通常是隐含的,如果两个插入由不同的线程运行,它们都将位于一个隐含的事务中,并且会看到数据库的一致视图。

票数 4
EN

Stack Overflow用户

发布于 2009-11-15 21:40:39

锁定整个表确实是过火了。为了达到你想要的效果,你需要一些被文学家称为“谓词锁”的东西。除了发表学术研究的论文外,没人见过其他人。其次是数据“访问路径”上的锁(在某些DBMS中:“页面锁”)。

有些非SQL系统允许您在一条语句中同时执行(1)和(2),这或多或少意味着操作系统在(1)和(2)之间挂起执行线程所产生的潜在竞争条件已经完全消除。

然而,在没有谓词锁的情况下,这类系统仍然需要采用某种类型的锁定方案,并且锁的“粒度”(/“范围”)越细,并发性越好。

(最后:一些DBMS--尤其是您不必付费的DBMS-确实没有比“整个表”更精细的锁粒度。)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/264807

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档