ActiveRecord, Sqlite3 и BusyException - PullRequest
1 голос
/ 12 мая 2011

У меня есть приложение rails, сконфигурированное со смешанными соединениями mysql и sqlite3 db, и чтобы связать определенные модели с sqlite3, я добавляю строку "create_connection 'sqlite_db_config_name'" в каждое определение класса.

Когда я пытаюсь сохранить любой объект модели, связанный с sqlite3, сохранение происходит успешно, но когда я пытаюсь сохранить объект, состоящий из других объектов (через has_many), я получаю исключение BusyException. У меня такое ощущение, что каждый объект имеет свое собственное соединение с БД, а объект верхнего уровня блокирует базу данных, затем вызывает методы сохранения объектов-членов, и они не могут получить блокировку.

Я предполагаю, что есть способ заставить эту работу работать, и я неправильно использую установившуюся связь.

Кто-нибудь еще сталкивался с этим?

database.yml config:

Dev:

development:
  adapter: mysql
  database: maindb
  username: root
  password:
  host: localhost

sqlite:
  adapter: sqlite3
  database: db/db.sqlite3
  timeout: 15000

определения модели:

class Foo < ActiveRecord::Base
  establish_connection 'sqlite'
  belongs_to :bar
end

class Bar < ActiveRecord::Base
  establish_connection 'sqlite'
  has_many :foo  
  def addFoo(item)
    self.foos << item
  end
end

class MysqlModel < ActiveRecord::Base
end

Другое:

Рубин 1,8,7
Рельсы 2.3.4
Ubuntu 10.04

Обновление:

Я попытался использовать наследование, чтобы изолировать оператор Estab_connection в одном классе, основываясь на объяснении dils rails doc: «Эта функция реализована путем сохранения пула соединений в ActiveRecord :: Base, который является хешем, проиндексированным классом. Если запрашивается соединение, метод retrieve_connection будет подниматься по иерархии классов до тех пор, пока соединение не будет найдено в пуле соединений. " Но по какой-то причине rails связывают подклассы класса sqlite-подключений с подключением по умолчанию для mysql. Поэтому я прекратил попытки установить отношение has_many / own_to с sqlite и отменил нормализацию своих моделей.

Ответы [ 2 ]

1 голос
/ 13 мая 2011

Я думаю, что "Install_connection 'sqlite'" вызывает проблемы.Попробуйте удалить это.SQLite допускает только одно соединение для записи на базу данных (файл)

Если вы выполняете множественную запись в базу данных, не закрывая ее, это приведет к тому, что Exception

Rails сможет обрабатывать соединение эффективно и автоматически,так что я думаю, что нам не нужно устанавливать связь отдельно.

0 голосов
/ 02 ноября 2012

Я обнаружил тупик на расширении sqlite3 ruby ​​и исправил его здесь: попробуйте и посмотрите, исправит ли это вашу проблему.


    https://github.com/dxj19831029/sqlite3-ruby

Я открыл запрос на получение ответа, от него больше нет ответа.

В любом случае ожидается некоторое исключение занятости, как описано в самом sqlite3.

Имейте в виду с этим условием: sqlite занят


    The presence of a busy handler does not guarantee that it will be invoked when there is 
    lock contention. If SQLite determines that invoking the busy handler could result in a 
    deadlock, it will go ahead and return SQLITE_BUSY or SQLITE_IOERR_BLOCKED instead of 
    invoking the busy handler. Consider a scenario where one process is holding a read lock 
    that it is trying to promote to a reserved lock and a second process is holding a reserved 
    lock that it is trying to promote to an exclusive lock. The first process cannot proceed 
    because it is blocked by the second and the second process cannot proceed because it is 
    blocked by the first. If both processes invoke the busy handlers, neither will make any 
    progress. Therefore, SQLite returns SQLITE_BUSY for the first process, hoping that this 
    will induce the first process to release its read lock and allow the second process to 
    proceed.

Если вы удовлетворяете этому условию, тайм-аут больше не действителен.Чтобы избежать этого, не помещайте select внутри begin / commit.или используйте эксклюзивную блокировку для начала / фиксации.

Надеюсь, это поможет.:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...