Comment `db.sérialiser les travaux des " nœud-sqlite3`
Récemment je suis en train d'apprendre à utiliser un nœud et nœud-sqlite3 à manipuler sqlite3, en voici un échantillon.
var sqlite3 = require('sqlite3');
var db = new sqlite3.Database(':memory:');
db.serialize(function() {
db.run("CREATE TABLE test(info TEXT)");
db.run("INSERT INTO test (info) VALUES ('info1')");
})
db.close();
La documentation dit que db.serialized
a été utilisé pour assurer SQL lignes ont été exécutés dans l'ordre, mais j'ai été confondu, pourquoi n'auraient-ils pas exécutés dans l'ordre, sans db.serialize
, après tout, ce serait retiré de la file d'attente d'événements et exécutées dans l'ordre? Comment ça marche ici?
Et si il y a une seule sql à exécuter, il est sûr de l'exécuter sans db.serialize
comme suit?
var sqlite3 = require('sqlite3');
var db = new sqlite3.Database(':memory:');
db.run("CREATE TABLE test(info TEXT)");
db.close();
- Probablement l'une des raisons: stackoverflow.com/a/18899872/1936319
Vous devez vous connecter pour publier un commentaire.
Chaque commande à l'intérieur de la
serialize()
fonction est assurée à finition l'exécution avant que le suivant ne commence.Dans votre exemple, le
CREATE TABLE
sera fini avant laINSERT
est exécuté. Si vous n'utilisez passerialize()
puis leCREATE TABLE
etINSERT
déclarations pourraient être exécutées en parallèle. Ils commencent donc rapidement l'une après l'autre lesINSERT
peut effectivement se terminer avant la création de la table, vous donnant une erreur en essayant d'insérer des données dans une table qui n'existe pas.Ce qui est appelé un condition de course, parce que chaque fois que vous exécutez votre programme, vous pourriez obtenir un gagnant différent. Si
CREATE TABLE
gagne la course alors que le programme fonctionne correctement. Mais siINSERT
remporte la course, le programme permettra de rompre avec une erreur. Puisque vous ne pouvez pas contrôler qui remporte la course,serialize()
arrêteraINSERT
même de commencer à, jusqu'à ceCREATE TABLE
a atteint la fin, vous assurant d'obtenir le même résultat à chaque fois.Dans votre deuxième exemple avec une seule instruction puis
serialize()
est toujours nécessaire. C'est parce querun()
commence la requête SQL, mais retourne immédiatement, laissant la requête à exécuter en arrière-plan. Depuis votre prochaine commande est l'une declose()
la base de données, vous aurez à couper tandis que la requête est toujours en cours d'exécution.Depuis
serialize()
n'a pas retourné jusqu'à ce que le dernier de ses requêtes internes a terminé, il vous permettra de tenir à distance lesclose()
jusqu'à ce que la requête est terminée.Si vous utilisez un autre type de requête (par exemple en réponse à un utilisateur de cliquer sur un bouton sur une page web, où la base de données est ouverte entre les appels), alors vous ne serait probablement pas besoin de
serialize()
. Il dépend seulement si le code qui suit chaque requête exige que les requêtes avant de l'avoir terminé ou pas.Avant de décider d'utiliser
serialize()
ou pas, il peut être utile de penser à tout non sérialisé des requêtes comme si ils sont commentées, et ensuite voir si le code fonctionne encore. Dans votre premier exemple ci-dessus, le retrait de laCREATE TABLE
commande de briser le suivantINSERT
déclaration (car alors il n'y aurait pas de table à insérer dans), donc ces le besoin d'être sérialisé. Mais si vous aviez deuxCREATE TABLE
commandes, puis la suppression de l'une n'aurait pas d'incidence sur les autres, de sorte que ces deux commandes n'aurait pas à être sérialisé.(Cette astuce ne s'applique pas à
close()
cependant - la règle de base, il y a seulement appelerclose()
une fois que tout est terminé en cours d'exécution.)run()
avoir un rappel, mais il semble que cela devrait être une nouvelle question plutôt que d'un commentaire de sorte que vous pouvez fournir plus de détails.J'ai trouvé ça dans le SQLite documentation:
Donc il semble que la réponse à votre question finale est oui. Si vous avez seulement une requête à exécuter, il n'y a pas besoin de la fonction serialize. Vous n'avez pas besoin de vous soucier de votre base de données se fermé avant que la requête se termine parce que SQLite est assez intelligent pour ne pas le faire! 🙂