【问题标题】:Rails In Transaction, why is entire database locked instead of single record?Rails In Transaction,为什么锁定整个数据库而不是单个记录?
【发布时间】:2019-03-14 02:47:22
【问题描述】:

我正在经历这个。在事务中,数据库本身是阻塞的,而不是单个记录。

这是我的代码的 sn-p。

代码 1)

lesson = Lesson.last
ActiveRecord::Base.transaction do
lesson.start_time = Time.now
  lesson.save
  sleep(10.seconds)
  raise "let's roll back lesson!!"
end

代码 2)

lesson = Lesson.first
lesson.start_time = Time.now
lesson.save

我在 console1 中执行 code1 并在 console2 中执行 code2,后者在另一个终端中打开。显然两个控制台在本地共享数据库。

代码 2 抛出类似的错误

ActiveRecord::StatementInvalid: SQLite3::BusyException: database is locked: UPDATE "lessons" SET "start_time" = ?, "updated_at" = ? WHERE "lessons"."id" = ?

我假设代码 1 会因为引发异常而阻止修改课程(Lesson.last)。它工作正常,但与我的预期不符的是代码 2 没有更新课程(Lesson.first)。

如果这是性质(阻塞整个数据库,而不是单个记录),那么复杂的业务逻辑最终会因为事务的停止而受到影响。

有点好奇!什么是让代码 2 正常工作的好策略!

【问题讨论】:

  • 我认为这个限制是在数据库连接上,而不是数据库本身
  • 是的,我同意@LeninRajRajasekaran,您可以在api.rubyonrails.org/classes/ActiveRecord/Transactions/… 中看到与锁定有关的内容。 “这是因为事务是每个数据库连接,而不是每个模型。”
  • 谢谢大家,当我增加本地(sqlite3)中的数据库连接池数量时,它实际上并没有帮助。但是,当我使用 mysql2 在生产模式下进行测试时,一切都按预期工作。 !

标签: ruby-on-rails transactions locking


【解决方案1】:

详细说明我们在 cmets 中写的内容:

ActiveRecord 事务是每个数据库连接,而不是每个模型。

https://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html

在开发环境中,Sqlite3 不支持concurrent modification 到数据库。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-20
    • 1970-01-01
    • 2011-04-09
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    相关资源
    最近更新 更多