ruby - 如何处理 'lock' 数据库行

标签 ruby database multithreading algorithm language-agnostic

我有一个充满行和多个线程的数据库,这些线程正在访问这些行,在一个函数中输入其中的一些数据,产生一个输出,然后用输出填充该行缺失的列。

这里是问题所在:每一行都有一个 unprocessed 标志,默认情况下为 true。所以每个线程都在寻找带有这个标志的行。但是每个线程都得到相同的行,事实证明...因为该行在线程的作业完成后被标记为已处理,这可能会在几秒钟后发生。

我避免这种情况的一种方法是为每一行插入一个 currently_processed 标志,将其标记为 false,一旦线程访问该行,将其更改为 true。然后当线程完成时,只需将 if 更改回 false。这个问题是我必须使用某种锁定,并且在这种情况发生之前不允许任何其他线程做任何事情。我想知道是否有一种替代方法,我不必进行线程锁定(通过互斥体或其他东西)从而减慢整个过程。

如果有帮助,代码是用 Ruby 编写的,但这个问题与语言无关,但这里是演示我正在使用的线程类型的代码。所以没什么特别的,就像几乎所有语言一样,在最低级别上进行线程化:

3.times do
  Thread.new do
   row = get_database_row
   result = do_some_processing(row)
   insert_results_into_row(result)
  end
end.each(&:join)

最佳答案

此处“真正”的答案是您需要一个数据库事务。当一个线程获取该行时,数据库 需要知道该行当前正在等待处理。

您不能在您的应用程序中解决这个问题!你看,当两个线程同时查看同一行时,它们可以尝试写入该标志……是的,它肯定会更改为“当前处理”;然后两个线程都将更新行数据并将其写回。如果任何处理导致相同的最终结果,那么这可能不是问题;但如果不这样做,就会出现各种数据完整性问题。

所以真正的答案是你退后一步,看看你的特定数据库是如何设计的,以便处理这些事情。

关于ruby - 如何处理 'lock' 数据库行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41691821/

相关文章:

c# - 用户登录失败。尝试访问 SQL Server Express 数据库

ruby-on-rails - 无法在 View Rails 4 中显示我的类别和子类别

ruby-on-rails - 在 Ruby 中用 HashWithIndifferentAccess 完全替换 Hash 不好吗?

PHP/MYSQL - 将其推向极限?

python - Django 中用户的默认类型是什么?

.net - 多线程变量访问

ruby-on-rails - 为什么 Rails Gemfile 默认为 https 而 http 使 bundler 更快?

ruby-on-rails - 如何在模块中为类方法起别名?

multithreading - 简化 VCL 线程包装器代码

java - 线程问题 : program doesn't start