我正在使用带有SQL后端(MySQL或Postgres)的Ruby On Rails(但这并不重要)。
该Web应用程序将是多进程的,并且在同一个DB上运行并运行着一组应用程序服务器进程。

我想知道:有什么好的通用策略来应对赛车条件吗?

由于它将成为一个DB密集型应用程序,因此我可以轻松地看到两个客户端如何尝试同时修改相同的数据。

让我们简化情况:

  • 两个客户端/用户获取相同的数据,这是否同时发生并不重要。
  • 它们带有两个表示相同数据的网页。
  • 后来他们俩都尝试对同一条记录进行一些不兼容的修改。

有没有一种简单的方法来处理这种情况?

我当时正在考虑使用与每个记录关联的id令牌。 记录更新时将更改此令牌,从而使基于陈旧数据的任何后续更新尝试均无效(旧的过期令牌)。

有没有更好的办法? 也许已经在MySQL中内置了某些东西? 我也对这种情况下使用的编码模式感兴趣。

谢谢

===============>>#1 票数:5 已采纳

乐观锁

在webapps中处理此问题的标准方法是使用所谓的“乐观锁定”。

每个记录都有一个唯一的ID和一个整数(或时间戳,但整数更好)乐观锁定字段。 创建记录时,此oplock字段将初始化为0。

当您获得记录时,您将获得oplock字段。

设置记录时,将oplock值设置为用SELECT加1检索到的oplock,并使UPDATE条件是oplock值仍然是上次查看时的值:

UPDATE thetable
SET field1 = ...,
    field2 = ...,
    oplock = 1
WHERE record_id = ...
  AND oplock = 0;

如果您在另一个会话中输了一场比赛,则该语句仍然会成功,但是它将报告受影响的零行。 这样一来,您便可以根据应用程序那部分的含义,告诉用户其更改与另一个用户的更改发生冲突,或者合并他们的更改并重新发送。

许多框架提供工具来帮助实现此目的,大多数ORM都可以立即使用。 Ruby on Rails支持乐观锁定

对于传统应用程序,将乐观锁定与悲观锁定(如下所述)结合使用时要小心。 它可以工作,你只需要添加上一个递增机会锁定列的所有乐观锁定的表触发UPDATE如果UPDATE语句并没有这样做了自我。 为Hibernate oplock支持编写了一个PostgreSQL触发器,该触发器应该很容易适应Rails。 仅当您要从Rails外部更新数据库时才需要这样做,但是在我看来,安全是一个好主意。

悲观锁定

更为传统的方法是在获取要修改的记录时开始事务并执行SELECT ... FOR UPDATE 然后,您可以使事务处于打开状态并处于空闲状态,而用户在考虑要执行的操作,并在COMMIT之前对已锁定的记录发出UPDATE

这不能很好地工作,我不建议这样做。 它要求每个用户进行一个开放的,通常是空闲的事务。 这可能会导致PostgreSQL中MVCC行清理的问题,并可能导致应用程序中的锁定问题。 对于拥有大量用户的大型应用程序,效率也非常低下。

插入种族

INSERT上处理种族要求您在表上拥有合适的应用程序级别的唯一键,因此,当插入冲突时,插入将失败。

  ask by tompave translate from so

未解决问题?本站智能推荐:

1回复

树注释的数据库方案

实现树注释的最佳方法是什么(每个注释可以有注释,那些注释也可以有注释)。 最多应包含10条评论。 我在PostgreSQL数据库中使用Rails。 显而易见的方法是这样做 但是我认为有一种更好的方法。
4回复

从数据库按字符串名称排序

我将字符串变量存储在数据库中,即“弃权”,“阻止”,“否”或“是”。 目前,我正在使用ORDER BY position来抓取这些,但是,我希望将它们排序为:“阻止”,“否”,“弃权”,“是”,而不是字母顺序。 在Rails中有一种简单的方法吗? 我的确切代码是: 注意:我正在
2回复

在数据库中按月分组,而不与ruby分组

我正在尝试按月对calls进行分组,但是我需要在数据库中而不是使用ruby进行分组。 这是当前代码: 哪个返回: 然后, ruby进行分组。 我应该怎么做才能使数据库起作用? 谢谢。
1回复

Rails基于行的数据库,大量请求

我设计了一个围绕短链接行的数据库。 我有以下架构: 该组织的基础是完全灵活的形式。 您只需在字段表中添加新行,然后该条目在生成学生的表单上定义一个新问题。 组是指选项字段,文本字段或地址。 保存数据后,与给定字段关联的组会告诉我的应用将其放入哪个表。此系统运行良好。 它非常
1回复

SQL数据库/.SQL文件到CSV文件

我正在使用Ruby on Rails编写一个应用程序,该应用程序将获取CSV文件并将数据迁移到postgresql数据库中,但是,我所有的数据都存储为.SQL文件或MS SQL 2008服务器上的数据库。 我想知道是否有可能编写一个简单的Ruby on Rails脚本并从SQL文件/ MS
2回复

使用SQL将数据库中的列与相等的行等同

表结构: 我需要运行一个查询,它会告诉我哪个uid与其他uid有相同的答案。 例如,这里有一些测试数据: 因此,我们可以从这些数据中看出,他们每个人都以同样的方式回答了3/4的问题。 我正在努力学习如何写一个查询,它会告诉我哪个uid匹配相同答案的3/4或4/4。 基本
1回复

在Rails中重构填充的SQL数据库

由于设计不良,我有一个数据库,该数据库在一个表中包含数据,实际上应该将其拆分为两个表。 该表提供了两种不同模型的数据。 我使用称为type的表字段来区分这些模型。 我用它来说if type == MODEL_A ... do foo ,还是if type == MODEL_
2回复

SQL数据库设计-类型表需要不同的子表?

首先,我感谢您的帮助。 我正在努力寻找一些数据库设计的最佳方法,而且我不确定要从哪里开始寻找我所追求的设计类型。 简而言之,我们有很多付款方式类型,例如现金,信用卡和贝宝。 但是,这些方法中的每一种都需要它们自己的参数集,以用于其设置详细信息(即,PayPal的API详细信息)以及
2回复

这个SQL查询如何将重复的值插入数据库?

背景:这是针对Ruby on Rails Web应用程序的。 我有一个后台工作,可以从Facebook下载最新帖子,并将其插入数据库。 我正在使用手工编码的SQL来提高性能。 RDBMS是PostgreSQL(在Heroku上)。 该表称为“帖子”。 我对posts.uid和pos
1回复

在PostgreSQL数据库中定期同步数据的最有效方法是什么?

我的PostgreSQL 9.0.x数据库中有一个名为cached_projects ,我主要通过Rails应用程序访问它,其架构如下所示: 该表由Rake任务填充,该任务每N分钟运行一次并执行以下操作: 查询来自SOAP Web服务的所有项目记录(此上下文中的“项目”仅包含名