当前位置: 首页 > 面试题库 >

递增字段时如何确保MySQL数据库中没有竞争条件?

岳迪
2023-03-14
问题内容

当两个连接要更新同一条记录时,如何防止MySQL数据库中的竞争状况?

例如,连接1要增加“尝试”计数器。第二个连接也想这样做。两个连接SELECT都“尝试”计数,增加值,两个UPDATE“尝试” 都增加值。突然,“
tries”仅是“ tries + 1”,而不是“ tries + 2”,因为两个连接都具有相同的“ tries”并将其增加1。

如何解决这个问题呢?


问题答案:

这是3种不同的方法:

原子更新

update table set tries=tries+1 where condition=value;

这将是原子完成的。

使用交易

如果确实需要首先选择该值并在应用程序中对其进行更新,则可能需要使用事务。这意味着您必须使用InnoDB,而不是MyISAM表。您的查询将类似于:

BEGIN; //or any method in the API you use that starts a transaction
select tries from table where condition=value for update;
.. do application logic to add to `tries`
update table set tries=newvalue where condition=value;
END;

如果事务失败,则可能需要手动重试。

版本方案

一种常见的方法是在表中引入版本列。您的查询将执行以下操作:

select tries,version from table where condition=value;
.. do application logic, and remember the old version value.
update table set tries=newvalue,version=version + 1 where condition=value and version=oldversion;

如果该更新失败/返回受影响的0行,则其他人在此同时更新了该表。您必须重新开始-也就是说,选择新值,执行应用程序逻辑,然后再次尝试更新。



 类似资料:
  • 问题内容: 我正在开发的应用程序中存在潜在的竞争状况,我想在查询中考虑和避免这种情况。 总结应用程序流程… 在表中创建一个新行: 通过查看对时间敏感的表格,找出Bar先生是否是获胜者: 如果他是赢家,请相应地更新他的条目行: 由于每个奖项只能颁发一次,因此我需要消除比赛条件的任何可能性,在这种情况下,另一个过程可以查询奖项表并更新上述步骤2和3之间的条目表。 我一直在做一些研究,发现了大量关于事务

  • 问题内容: 如何停止MySQL中的竞争条件?当前的问题是由一个简单的算法引起的: 从表中选择一行 如果不存在,将其插入 然后会得到重复的行,或者如果您通过唯一/主键阻止它,则会出现错误。 现在,通常我认为事务在这里有所帮助,但是由于该行不存在,所以事务实际上并没有帮助(或者我是否错过了什么?)。 LOCK TABLE听起来有些矫kill过正,尤其是如果该表每秒更新多次。 我唯一想到的其他解决方案是

  • 9.1. 竞争条件 在一个线性(就是说只有一个goroutine的)的程序中,程序的执行顺序只由程序的逻辑来决定。例如,我们有一段语句序列,第一个在第二个之前(废话),以此类推。在有两个或更多goroutine的程序中,每一个goroutine内的语句也是按照既定的顺序去执行的,但是一般情况下我们没法去知道分别位于两个goroutine的事件x和y的执行顺序,x是在y之前还是之后还是同时发生是没法

  • 9.6. 竞争条件检测 即使我们小心到不能再小心,但在并发程序中犯错还是太容易了。幸运的是,Go的runtime和工具链为我们装备了一个复杂但好用的动态分析工具,竞争检查器(the race detector)。 只要在go build,go run或者go test命令后面加上-race的flag,就会使编译器创建一个你的应用的“修改”版或者一个附带了能够记录所有运行期对共享变量访问工具的tes

  • 我现在正在使用适用于Android的Firestore;记录一些数据并将其写入文档。与其每次都创建文档,我想限制 10 个或一些 x 个字段的文档。如果用户写入文档并且字段计数达到 x,则用户将在同一集合中创建新文档。 所以我的问题是:在创建新文档(由不同用户创建的多个文档)时,如何避免竞争条件?使用这种方法将此类数据拆分为不同的文档是否可行?

  • 我有一个应用程序在Symfony需要发送电子邮件/通知从应用程序。由于电子邮件/通知发送过程需要时间,所以我决定将它们放入队列中,并定期处理队列。因此,我可以减少涉及电子邮件/通知分派的请求的响应时间。 处理队列的Cron作业(一个php脚本-Symfony路由)每30秒运行一次,检查是否有未发送的电子邮件/通知,如果发现,它将从队列表中获取所有数据并开始发送它们。当发送电子邮件/通知时,队列表行