【问题标题】:Change database connection at runtime在运行时更改数据库连接
【发布时间】:2013-01-29 11:52:54
【问题描述】:

给定

我有一个模型需要连接到专用的内存 SQLite 数据库。我正在做的是——像这样在类级别创建一个连接(这里我使用ExternalDatabase提供的连接跳过架构定义):

class ExternalDatabase < ActiveRecord::Base
  self.abstract_class = true

  establish_connection(adapter: 'sqlite', database: ':memory:')
end

class MyModel < ExternalDatabase
end

问题

我怀疑上面的定义在从多个线程访问时容易出错。一个很好的例子是在运行 Sidekiq 工作线程时同时从它们的线程写入数据库。

所以问题是:

  1. 我对从不同线程访问数据库时发生读/写冲突的怀疑是否正确? sqlite 是否将资源锁定在较低级别,从而实现对读/写的安全并发访问?

  2. 如何在运行时为给定模型更改与内存中 SQLite 数据库的连接? ActiveRecord::Base#establish_connection 不适合我,因为我使用的是内存数据库。

    我想实现这样的目标:

    klass = Class.new(ActiveRecord::Base)
    klass.establish_connection(adapter: 'sqlite', database: ':memory:')  
    
    create_schema(klass.connection)
    
    MyClass.connection = klass.connection
    

    但是 Rails 在 ActiveRecord::Base 上缺少直接的 #connection= 方法(尽管它有未记录的 #connection_id 似乎仍然不起作用。

【问题讨论】:

    标签: ruby-on-rails multithreading sqlite database-connection


    【解决方案1】:

    得出两个结论:

    1. 对于内存中的 DB,线程始终获得唯一的连接,即它自己的 DB 版本,始终是“新鲜的”,并且不会与其他线程中的类似 DB 发生干扰。
    2. 对于常规 DB,应确保在运行时而不是在类定义中建立连接。

    【讨论】:

      【解决方案2】:

      这可能有用。

      http://www.sqlite.org/faq.html#q6

      我对它的快速阅读表明,您可以通过多个步骤访问同一个 sqlite 数据库,但您应该尽量避免这样做,并且会带来一些陷阱。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-11
        • 1970-01-01
        • 1970-01-01
        • 2018-03-07
        • 2013-09-21
        • 2013-01-11
        • 1970-01-01
        • 2020-08-19
        相关资源
        最近更新 更多