SQLite possède un verrouillage lecteurs-écrivains au niveau de la base de données. Plusieurs connexions (appartenant éventuellement à des processus différents) peuvent lire les données de la même base de données en même temps, mais une seule peut écrire dans la base de données.
SQLite supporte un nombre illimité de lecteurs simultanés, mais ne permet qu'un seul écrivain à un moment donné. Dans de nombreuses situations, ce n'est pas un problème. Mise en file d'attente des scripteurs. Chaque application fait son travail de base de données rapidement et passe à autre chose, et aucun verrou ne dure plus de quelques dizaines de millisecondes. Mais il y a des applications qui nécessitent plus de concurrence, et ces applications peuvent avoir besoin de chercher une solution différente. -- Utilisations appropriées de SQLite @ SQLite.org
Le verrou lecteur-écrivain permet un traitement indépendant des transactions et il est mis en œuvre à l'aide de verrous exclusifs et partagés au niveau de la base de données.
Un verrou exclusif doit être obtenu avant qu'une connexion n'effectue une opération d'écriture sur une base de données. Après l'obtention du verrou exclusif, les opérations de lecture et d'écriture des autres connexions sont bloquées jusqu'à ce que le verrou soit libéré.
Détails d'implémentation pour le cas des écritures simultanées
SQLite dispose d'une table de verrouillage qui permet de verrouiller la base de données le plus tard possible lors d'une opération d'écriture afin de garantir une concurrence maximale.
L'état initial est UNLOCKED, et dans cet état, la connexion n'a pas encore accédé à la base de données. Lorsqu'un processus est connecté à une base de données et que même une transaction a été lancée avec BEGIN, la connexion est toujours dans l'état UNLOCKED.
Après l'état UNLOCKED, l'état suivant est l'état SHARED. Pour pouvoir lire (et non écrire) des données dans la base de données, la connexion doit d'abord passer à l'état SHARED, en obtenant un verrou SHARED. Plusieurs connexions peuvent obtenir et maintenir des verrous SHARED en même temps, de sorte que plusieurs connexions peuvent lire des données de la même base de données en même temps. Mais tant qu'un seul verrou SHARED n'est pas libéré, aucune connexion ne peut mener à bien une écriture dans la base de données.
Si une connexion veut écrire dans la base de données, elle doit d'abord obtenir un verrou RESERVÉ.
Un seul verrou RESERVED peut être actif à la fois, mais plusieurs verrous SHARED peuvent coexister avec un seul verrou RESERVED. RESERVED diffère de PENDING en ce que de nouveaux verrous SHARED peuvent être acquis tant qu'il y a un verrou RESERVED. -- Verrouillage de fichiers et concurrence dans SQLite Version 3 @ SQLite.org
Une fois qu'une connexion obtient un verrou RESERVÉ, elle peut commencer à traiter les opérations de modification de la base de données, bien que ces modifications ne puissent être effectuées que dans le tampon, plutôt que d'être réellement écrites sur le disque. Les modifications apportées au contenu de la lecture sont enregistrées dans le tampon de mémoire. Lorsqu'une connexion veut soumettre une modification (ou une transaction), il est nécessaire de transformer le verrou RESERVED en verrou EXCLUSIVE. Pour obtenir le verrou, il faut d'abord lever le verrou vers un verrou PENDING.
Un verrou PENDING signifie que le processus qui détient le verrou veut écrire dans la base de données dès que possible et attend simplement que tous les verrous SHARED actuels soient levés pour pouvoir obtenir un verrou EXCLUSIVE. Aucun nouveau verrou SHARED n'est autorisé sur la base de données si un verrou PENDING est actif, mais les verrous SHARED existants peuvent continuer.
Un verrou EXCLUSIF est nécessaire pour pouvoir écrire dans le fichier de la base de données. Un seul verrou EXCLUSIF est autorisé sur le fichier et aucun autre verrou de quelque nature que ce soit ne peut coexister avec un verrou EXCLUSIF. Afin de maximiser la concurrence, SQLite s'efforce de minimiser le temps pendant lequel les verrous EXCLUSIFS sont maintenus. -- Verrouillage de fichiers et concurrence dans SQLite Version 3 @ SQLite.org
On pourrait donc dire que SQLite ne gère pas les accès concurrents de plusieurs processus écrivant dans la même base de données simplement parce qu'il ne le supporte pas ! Vous obtiendrez SQLITE_BUSY
o SQLITE_LOCKED
pour le second auteur lorsqu'il atteint la limite de réessai.
5 votes
J'ai oublié de mentionner le prime goall : la plupart des réponses disent que c'est bon : "mais, à mon avis, ne répondent pas en détail / n'expliquent pas clairement ce qui se passe si deux opérations d'écriture arrivent exactement au même moment (cas théorique très rare). 1) Est-ce que cela déclencherait une erreur et interromprait le programme ? ou 2) Est-ce que la deuxième opération d'écriture attendrait que la première soit terminée ? ou 3) Est-ce que l'une des opérations d'écriture serait abandonnée (perte de données !)? 4) Autre chose ? Connaître les limites de l'écriture simultanée peut être utile dans de nombreuses situations.
7 votes
@Basj En bref,2)il attendra et réessayera plusieurs fois(configurable),1)déclenchera une erreur,SQLITE_BUSY.3)vous pouvez enregistrer un Callback pour gérer les erreurs SQLITE_BUSY.