如何在MySQL中停止比赛条件?当前的问题是由一个简单的算法引起的:
然后要么得到一个重复的行,要么通过唯一/主键防止它发生错误。
现在,我通常认为事务在这里有所帮助,但是由于行不存在,事务实际上没有帮助(还是我遗漏了什么?)
锁表听起来有点过火,特别是如果表每秒更新多次的话。
我能想到的唯一其他解决方案是针对每个不同id的GET_LOCK(),但是没有更好的方法吗?这里也没有可伸缩性问题吗?而且,对每个表都这样做听起来有点不自然,因为在我看来,这在高并发数据库中是一个非常常见的问题。
发布于 2008-11-05 10:44:24
发布于 2008-11-05 10:45:23
在我看来,您应该在id列上有一个唯一的索引,因此重复插入将触发错误,而不是再次盲目地接受。
这可以通过将id定义为主键或单独使用唯一索引来完成。
我认为您需要问的第一个问题是,为什么有许多线程在执行完全相同的工作?他们为什么要插入完全相同的一行?
在得到答案之后,我认为忽略错误将是最有效的解决方案,但是度量这两种方法(GET_LOCK v/s忽略错误)并亲自查看。
据我所知,没有别的办法了。为什么要避免错误?当发生另一种类型的错误时,您仍然必须为这种情况编写代码。
正如staticsan说的那样,事务确实有帮助,但是,由于它们通常是隐含的,如果两个插入由不同的线程运行,它们都将位于一个隐含的事务中,并且会看到数据库的一致视图。
发布于 2009-11-15 21:40:39
锁定整个表确实是过火了。为了达到你想要的效果,你需要一些被文学家称为“谓词锁”的东西。除了发表学术研究的论文外,没人见过其他人。其次是数据“访问路径”上的锁(在某些DBMS中:“页面锁”)。
有些非SQL系统允许您在一条语句中同时执行(1)和(2),这或多或少意味着操作系统在(1)和(2)之间挂起执行线程所产生的潜在竞争条件已经完全消除。
然而,在没有谓词锁的情况下,这类系统仍然需要采用某种类型的锁定方案,并且锁的“粒度”(/“范围”)越细,并发性越好。
(最后:一些DBMS--尤其是您不必付费的DBMS-确实没有比“整个表”更精细的锁粒度。)
https://stackoverflow.com/questions/264807
复制相似问题