web-dev-qa-db-fra.com

Ruby: SQLite3 :: BusyException: la base de données est verrouillée:

Couru dans ce message d'erreur tout en développant ce soir: SQLite3::BusyException: database is locked:

J'ai deux modèles: 

  • Les podcasts ont de nombreuses pistes 
  • Les pistes appartiennent aux podcasts.
  • Les fichiers podcast sont hébergés sur mixcloud .

Pour créer un podcast:

  • l'utilisateur soumet une URL pour un podcast sur mixcloud
  • L'application Rails saisit le flux JSON associé à l'URL
  • json est utilisé pour définir des attributs (titre, image, etc.) sur le nouvel objet Podcast

J'essaie de faire en sorte que mon application Rails tire parti du fait que le fil json détaille également les noms (et artistes) des morceaux appartenant à ce podcast.

Je pensais que la méthode before_validation suivante créerait automatiquement toutes les pistes associées chaque fois que nous créons un nouveau podcast.

class Podcast < ActiveRecord::Base
  attr_accessible :mixcloud_url, :lots, :of, :other, :attrs
  has_many :tracks    
  before_validation :create_tracks
  def create_tracks
    json = Hashie::Mash.new HTTParty.get(self.json_url)    
    json.sections.each do |section|
      if section.section_type=="track"
          Track.create(:name=>section.track.name, :podcast_id=>self.id)
      end
    end             
  end
end

Comment puis-je contourner cela? Il semble que Rails (ou sqlite3) ne m'aime pas créer de nouvelles instances d'un modèle associé de cette manière. Comment puis-je faire cela? Je pense que cela est autant un problème de Rails qu’un problème de SQLite3. Je peux poster plus de code si ça va aider.

39
stephenmurdoch

Si vous rencontrez ce problème avec le verrouillage SQLite en développement lorsque la console Rails est ouverte, essayez ceci:

Il suffit de lancer ce qui suit:

ActiveRecord::Base.connection.execute("BEGIN TRANSACTION; END;")

Pour moi de toute façon, il semble effacer toute transaction que la console conservait et libérer la base de données.

Ceci est particulièrement un problème pour moi lors de l'exécution de delay_job, ce qui semble échouer assez souvent lors de la clôture de la transaction.

60
trisweb

Pour moi ... le problème que j’avais était qu’il semblait que la console Rails que j’avais ouverte pendant un moment bloquait une connexion avec SQLite.

Donc, une fois que j'ai quitté cette console et redémarré mon serveur Web (Thin), cela a parfaitement fonctionné.

J'ai essayé la suggestion de @ trisweb mais cela n'a pas fonctionné pour moi.

22
marcamillion

SQLite n'est pas vraiment censé être utilisé pour un accès simultané, problème que vous rencontrez ici. Vous pouvez essayer d'augmenter le délai dans votre fichier database.yml, ce qui peut constituer une solution de contournement dans ce cas. Cependant, je vous recommanderais de passer à une autre base de données prenant en charge plusieurs connexions telles que MySQL ou PgSQL.

21
Devin M

J'avais le même "ActiveRecord :: StatementInvalid: SQLite3 :: BusyException: la base de données est verrouillée: INSERT INTO" utilisateurs "(" created_at "," email "," nom "," password_digest "," updated_at ") VALEURS (?,? , ?, ?, ?)" problème. J'ai essayé tous les moyens trouvés dans Google et j'ai échoué. Le problème a été résolu pour moi lorsque j'ai fermé mon navigateur de base de données SQLite.

14
Tarique

Assurez-vous de ne pas avoir 2 gardes ou plusieurs consoles en marche .. Si vous voulez, assurez-vous de voir désespérément la réponse "Sans nom" ci-dessus.

Vous pouvez également essayer d'augmenter la piscine:

par exemple: changez la section de test dans votre config/database.yml comme ci-dessous

test:
    adapter: sqlite3
    database: db/test.sqlite3
    pool: 50
    timeout: 5000
5
Luke

Vous avez probablement une console Rails ouverte sur une autre bash, si vous devez la fermer (ctrl + D). 

2
ark1980

Ce n'est probablement pas lié au code Rails. L'utilisation simultanée de la console avec l'option sandbox (Rails console --sandbox) rend le problème systématique avec SQLite, car la console attend essentiellement de quitter pour tout annuler. 

La solution ci-dessus de @trisweb ne fonctionnera pas dans ce cas, mais quitter la console fonctionnera.

1
Antoine Lizée

en fait pour moi, j'ai trouvé tuer Rails aider à résoudre ce problème.

utilisez "ps aux | grep Rails" pour connaître l'ID du processus Rails en cours . puis utilisez

"kill -9 [Rails-pid]"

tuer les processus.

Alors ça va marcher

1
BufBills

J'utilisais Navigateur DB pour SQLite et la console Rails simultanément. Fermer le DB Browser for SQLite a résolu le problème pour moi.

0
webster

mon problème est le suivant: j'ai ouvert un programme de gestion de base de données nommé "DB Browser for SQlite". Fermez ce programme de gestion de base de données et le problème est résolu. 

0
hofffman

Cela se produit lorsque vous apportez directement des modifications directement dans le navigateur de base de données SQlite (par exemple, vous supprimez une ligne ou modifiez la valeur d'une colonne) sans que vous enregistriez ces modifications. Toutes les modifications apportées doivent être enregistrées (ctrl + s). S'il n'est pas enregistré, SQLite verrouille la base de données jusqu'à ce que vous sauvegardiez ces modifications. 

J'ai fait la même chose et mon problème a été résolu!

0
Shubham Aggarwal

SQLite a des problèmes avec la concurrence . J'ai changé sqlite sur Postgresql et le problème a disparu

0
itsnikolay

J'ai eu le même problème. Pour ceux avec SQLite Database Browser. Je n'avais pas besoin de fermer SQLite Database Browser. Je n'avais qu'à cliquer sur le bouton "Ecrire les modifications". Il est mis en évidence et ne doit pas être mis en évidence. 

0
jesse lawson

Oui c'est une vieille question et il y a déjà beaucoup de réponses ici. Mais aucun d'entre eux n'a fonctionné pour moi, ce qui signifie qu'il m'a fallu beaucoup de temps pour enfin comprendre le problème. J'ai trouvé ce qui a fonctionné et le partage au cas où ce serait la cause du problème pour vous aussi.

J'utilisais le navigateur SQLITE (c'est un navigateur de base de données graphique). Je vais me référer à cela comme "interface graphique" ici (pour éviter toute confusion avec le navigateur Word étant votre navigateur chromehôtehôte :: 8000 ou autre chose.
http://sqlitebrowser.org/

Je surveillais ce qui était écrit dans la base de données et l'interface graphique était ouverte pendant que mon application Rails s'exécutait dans mon navigateur Chrome. Je voudrais actualiser l'interface graphique pour voir si elle ajoutait les données comme je le souhaitais.

En ce qui concerne le débogage, j'avais décidé de supprimer une ligne de l'interface graphique SQLite afin de voir si mon application réagirait correctement si la ligne manquait maintenant.

En fin de compte, le navigateur SQLite ne supprime pas la ligne (ce qui me confond avec la raison pour laquelle mon application agissait comme si la ligne était toujours présente, même si elle manquait visuellement sur l'interface graphique). Quoi qu'il en soit, après 30 minutes de frustration, j'ai fermé l'interface graphique de SQLite, puis un avis m'a demandé si je voulais enregistrer les modifications apportées à la base de données que j'avais apportées. J'ai naïvement cliqué sur "Non" et fermé l'application.

Apparemment, ce qui se passe, c'est que l'interface graphique a ensuite verrouillé la base de données, car certaines lignes de ma base de données avaient été en quelque sorte "supprimées de manière logicielle" sans que la suppression ait été validée. Donc, l'interface graphique était (faute d'un meilleur terme) contenant la base de données dans Limbo.

Cela explique pourquoi a) mon application ne s'est pas comportée comme si la ligne était manquante, car elle n'avait pas encore été supprimée. B) explique pourquoi la base de données a été verrouillée. J'attendais toujours que je commette les suppressions.

Donc, pour résoudre le problème, j'ai simplement ouvert à nouveau l'interface graphique, supprimé la même ligne, puis fermé l'interface graphique. Cette fois, j'ai cliqué sur "Oui" pour demander l'enregistrement des modifications apportées à la base de données. Il a enregistré la suppression et déverrouillé la base de données et maintenant mon application fonctionne!


J'espère que cela a aidé quelqu'un qui pourrait avoir le même problème mais qui utilisait l'interface graphique du navigateur SQLite. Cela pourrait être le verrouillage de votre base de données.

0
jacurtis

essayez de redémarrer le serveur ou de fermer une console Rails en cours d'exécution.

0
Aishwarya Singhal