Dois-je verrouiller des lignes dans ma base de données cloud pendant qu'elles sont modifiées par un utilisateur

12

Je crée une application de bureau qui conserve les données dans le cloud. Une préoccupation que j'ai est de commencer à modifier un élément dans l'application et de le laisser pendant un certain temps, ce qui rend les données obsolètes. Cela peut évidemment aussi se produire si 2 personnes essaient de modifier le même élément en même temps. Quand ils ont terminé leur édition et veulent enregistrer les données, je devrais soit écraser ce qui existe actuellement dans la base de données, soit vérifier qu'ils ont commencé à éditer après la dernière modification et les forcer à annuler leurs modifications ou peut-être leur donner la possibilité de risquer écraser les changements de quelqu'un d'autre.

J'ai pensé à ajouter un champs is_lockedet lock_timestampà la table DB. Lorsqu'un utilisateur commence à modifier l'élément, la ligne devient is_lockedtrue et définit l'horodatage du verrouillage sur l'heure actuelle. J'aurais alors un certain temps pendant lequel le verrou est maintenu (ex. 5 minutes). Si quelqu'un d'autre tente de modifier l'élément, il recevra un message lui indiquant que l'élément est verrouillé et que le verrouillage expire automatiquement. Si l'utilisateur s'éloigne pendant la modification, le verrou expirera automatiquement après une période de temps relativement courte et une fois qu'il le fera, l'utilisateur sera averti que le verrou a expiré et sera obligé de redémarrer la modification après la régénération des données.

Serait-ce une bonne méthode pour empêcher l'écrasement des données périmées? Est-ce exagéré (je ne m'attends pas à ce que l'application soit utilisée par plus de quelques personnes simultanément sur un seul compte).

(Une autre préoccupation que j'ai est que 2 personnes obtiennent un verrou pour le même article, mais je pense que c'est une condition de course avec laquelle je suis à l'aise.)

yitzih
la source
1
"Une autre préoccupation que j'ai est que 2 personnes obtiennent un verrou pour le même article, mais je pense que c'est une condition de concurrence avec laquelle je suis à l'aise" - l'utilisation d'une transaction de base de données autour de l'acquisition du verrou devrait empêcher de telles conditions de concurrence.
Jules
La plupart des moteurs de base de données (du type relationnel, au moins) ont un support intégré pour cela. C'est un concept très courant dans le monde du SGBDR, et même les bases de données "jouets" le gèrent assez bien, étant donné que vous lui dites que vous voulez un verrouillage optimiste ou pessimiste. Quoi qu'il en soit, je ne pense pas que ce soit quelque chose dont vous avez besoin pour vous construire par tous les moyens: vérifiez les options de votre moteur de base de données pour voir comment travailler avec.
jleach
Le fait que votre application soit une application de bureau (un gros client ) ne fait pas beaucoup de différence. Il peut être conçu de la même manière qu'une application serveur multi-instance hautement disponible.
Hosam Aly

Réponses:

19

Une chose qui vous aidera ici est la terminologie. Ce que vous décrivez ici est appelé «verrouillage pessimiste». La principale alternative à cette approche est le «verrouillage optimiste». Dans le verrouillage pessimiste, chaque acteur doit verrouiller l'enregistrement avant de le mettre à jour et le libérer lorsque la mise à jour est terminée. Dans le verrouillage optimiste, vous supposez que personne d'autre ne met à jour l'enregistrement et essayez. La mise à jour échoue si l'enregistrement a été modifié par un autre acteur.

Le verrouillage optimiste est généralement préférable si les chances que deux acteurs mettent à jour la même chose en même temps sont faibles. Pessimiste est généralement utilisé lorsque cette chance est élevée ou que vous devez savoir que votre mise à jour pourra réussir avant votre départ. D'après mon expérience, le verrouillage optimiste est presque toujours préférable car il existe de nombreux problèmes inhérents au verrouillage pessimiste. L'un des plus gros problèmes est abordé dans votre question. Les utilisateurs peuvent verrouiller un enregistrement pour le modifier, puis partir pour le déjeuner. Votre atténuation vous y aidera, mais l'expérience utilisateur ne sera pas meilleure que l'approche optimiste et sera probablement bien pire. Par exemple, un utilisateur ouvre un enregistrement, commence à le mettre à jour et son patron apparaît à son bureau. Un autre utilisateur essaie de modifier l'enregistrement. Il est verrouillé. Le deuxième utilisateur continue d'essayer et après 5 minutes, le verrou expire et le deuxième utilisateur met à jour l'enregistrement. Le premier utilisateur revient à l'écran, essaie de sauvegarder et on lui dit qu'il a perdu son verrou. Maintenant, dans le même scénario avec tout la même chose, sauf en utilisant le verrouillage optimiste, l'expérience du premier utilisateur est à peu près la même, mais le deuxième utilisateur n'attend pas 5 minutes.

Le schéma que vous disposez serait considérablement amélioré en implémentant un verrouillage optimiste pour la valeur de verrouillage, mais mon intuition est que le verrouillage optimiste est probablement OK pour le tout et vous pouvez vous débarrasser du champ is_locked.

Vous ne fournissez pas la «base de données cloud» que vous utilisez. Vous devriez probablement examiner les fonctionnalités de cela pour voir s'il existe des fonctionnalités intégrées avant d'implémenter votre propre solution.

Voici la recette de base: au lieu d'un champ is_locked, ayez un champ de numéro de version. Lorsque vous récupérez l'enregistrement, vous extrayez la version actuelle de l'enregistrement. Lorsque vous mettez à jour, vous subordonnez la mise à jour au champ de version correspondant à ce que vous avez récupéré et l'incrémentez en cas de succès. Si la version ne correspond pas, la mise à jour n'a aucun effet et vous la signalez comme un échec.

JimmyJames
la source
Ceci est une réponse très utile. Pouvez-vous expliquer pourquoi le verrouillage pessimiste est déconseillé quand il y a une petite chance de "collisions". Est-ce uniquement parce qu'il nécessite d'aller dans la base de données pour commencer à éditer, ou à cause d'une complexité supplémentaire ou pour une autre raison? Merci!
yitzih
3
@yitzih Quelques suggestions de lecture: Fowler et al, Patterns of Enterprise Application Architecture . Il y a un chapitre entier sur cette question, avec une bonne discussion sur toutes les options et les raisons de les choisir.
Jules
2
@Jimmy - Votre réponse est très bien. Dans certains cas, le signalement d'une erreur ne suffit pas. Prenons un cas où un utilisateur passe quelques minutes à mettre à jour un enregistrement. Dans ce cas, l'échec peut ne pas être suffisant, il peut être utile de donner à l'utilisateur la possibilité de fusionner ses modifications en vol avec celles commises par l'autre utilisateur. J'aurais dû dire qu'un verrouillage optimiste peut nécessiter une résolution de conflit en fonction de vos besoins.
Jon Raynor
3
Il convient de mentionner que le verrouillage pessimiste est beaucoup plus facile à expliquer au client. Si vous écrivez un message indiquant que le client ne peut pas accéder à l'enregistrement car il est en cours de modification par un autre, le client comprend très bien et l'accepte généralement. Si au lieu de cela, vous dites au client après l'enregistrement que la sauvegarde n'a pas été possible car elle a déjà été mise à jour par un autre utilisateur, 7/10, le client sera frustré et / ou attendra des explications pour cet étrange comportement du programme.
Neil
2
@Neil C'est vrai et je pense que c'est souvent pourquoi le verrouillage pessimiste est utilisé lorsque l'optimisme est plus approprié. Souvent, le flux de travail rend très peu probable une collision.
JimmyJames
0

À partir de la réponse de @ JimmyJames , nous pouvons voir comment la question concerne vraiment l'expérience utilisateur .

Tout dépend du contexte. Combien de temps et d'efforts faut-il pour mettre à jour un enregistrement? À quelle fréquence plusieurs utilisateurs souhaitent-ils mettre à jour le même document?

Par exemple, si vos utilisateurs prennent généralement quelques secondes pour mettre à jour l'enregistrement et qu'il y a peu de conflits, un verrouillage optimiste est probablement la solution. Au pire, un utilisateur devra passer quelques secondes de plus, peut-être jusqu'à une minute, pour mettre à jour un document.

Si votre document est très controversé mais bien structuré, vous pouvez peut-être leur permettre de verrouiller des champs individuels par incréments de 30 secondes, en affichant un minuteur ou une notification discrète pour leur permettre d'étendre le verrouillage.

Cependant, si vos utilisateurs passent beaucoup de temps ou d'efforts, vous devriez envisager d'autres approches. Votre dossier est-il bien structuré? Pourriez-vous montrer aux utilisateurs une comparaison (un diff) entre la version sur le serveur et la version qu'ils essaient d'enregistrer? Pouvez-vous mettre en évidence les différences? Pouvez-vous les laisser fusionner les modifications? Pensez à l'expérience que vous souhaitez vivre avec vos outils de contrôle de code source. Vous ne voulez vraiment pas être obligé d'écrire à nouveau tout ce code!

Vous pouvez consulter Google Docs pour plus d'inspiration. Vous pouvez peut-être montrer aux utilisateurs une notification qu'une nouvelle version a été enregistrée. Vous pouvez peut-être leur montrer combien de personnes ont ouvert le dossier afin qu'elles puissent choisir de revenir à un moment moins litigieux.

Hosam Aly
la source