sql server - Modification des enregistrements de base de données par plusieurs utilisateurs

Translate

J'ai conçu des tables de base de données (normalisées, sur un serveur MS SQL) et créé une interface Windows autonome pour une application qui sera utilisée par une poignée d'utilisateurs pour ajouter et modifier des informations. Nous ajouterons une interface Web pour permettre la recherche dans notre zone de production à une date ultérieure.

Je crains que si deux utilisateurs commencent à modifier le même enregistrement, le dernier à valider la mise à jour serait le «gagnant» et des informations importantes pourraient être perdues. Un certain nombre de solutions me viennent à l'esprit mais je ne sais pas si je vais créer un plus gros mal de tête.

  1. Ne faites rien et espérez que deux utilisateurs ne modifieront jamais le même enregistrement en même temps.- Ça n'arrivera peut-être jamais, mais que faire si ça arrive?
  2. La routine d'édition pourrait stocker une copie des données d'origine ainsi que les mises à jour, puis comparer lorsque l'utilisateur a terminé l'édition. S'ils diffèrent, afficher l'utilisateur et confirmer la mise à jour- Nécessiterait le stockage de deux copies des données.
  3. Ajoutez la dernière colonne DATETIME mise à jour et vérifiez qu'elle correspond lorsque nous mettons à jour, sinon montrez les différences.- nécessite une nouvelle colonne dans chacun des tableaux concernés.
  4. Créez une table d'édition qui enregistre lorsque les utilisateurs commencent à modifier un enregistrement qui sera vérifié et empêchera d'autres utilisateurs de modifier le même enregistrement.- nécessiterait une réflexion attentive sur le déroulement du programme pour éviter les blocages et le verrouillage des enregistrements si un utilisateur tombe en panne hors du programme.

Existe-t-il de meilleures solutions ou devrais-je opter pour l'une d'entre elles?

This question and all comments follow the "Attribution Required."

Toutes les réponses

Translate

Si vous vous attendez à des collisions peu fréquentes,Concurrence optimisteest probablement votre meilleur pari.

Scott Mitchell a écrit un tutoriel complet sur la mise en œuvre de ce modèle:
Implémentation de la concurrence optimiste

La source
AJ.
Translate

Une approche classique est la suivante:

  • ajoutez un champ booléen, "verrouillé" à chaque table.
  • définissez ceci sur false par défaut.
  • lorsqu'un utilisateur commence à modifier, procédez comme suit:

    • verrouiller la ligne (ou la table entière si vous ne pouvez pas verrouiller la ligne)
    • vérifiez le drapeau sur la ligne que vous souhaitez modifier
    • if the flag is true then
      • informer l'utilisateur qu'il ne peut pas modifier cette ligne pour le moment
    • else
      • définir l'indicateur sur true
    • relâchez le verrou

    • lors de la sauvegarde de l'enregistrement, redéfinissez l'indicateur sur false

La source
Julian Lee
Translate

SELECT FOR UPDATE et les équivalents sont bons à condition que vous mainteniez le verrou pendant un laps de temps microscopique, mais pour une quantité macroscopique (par exemple, l'utilisateur a chargé les données et n'a pas appuyé sur `` enregistrer '', vous devez utiliser la concurrence optimiste comme ci-dessus. Je pense toujours que c'est mal nommé - c'est plus pessimiste que «le dernier écrivain gagne», qui est généralement la seule autre alternative envisagée.)

La source
Translate

@ Mark Harrison: SQL Server ne prend pas en charge cette syntaxe (SELECT ... FOR UPDATE).

L'équivalent SQL Server est leSELECTindice de déclarationUPDLOCK.

VoirDocumentation en ligne de SQL Serverpour plus d'informations.

La source
Translate

-d'abord créer un fichier (heure de mise à jour) pour stocker le dernier enregistrement de mise à jour -lorsqu'un utilisateur sélectionne l'enregistrement enregistrer l'heure de sélection, comparer entre l'heure de sélection et le champ d'heure de mise à jour si (heure de mise à jour)> (heure de sélection) cela signifie qu'un autre utilisateur met à jour cet enregistrement après la sélection record

La source
Guy
Translate

Une autre option consiste à tester que les valeurs de l'enregistrement que vous modifiez sont toujours les mêmes que lorsque vous avez commencé:

SELECT 
    customer_nm,
    customer_nm AS customer_nm_orig
FROM demo_customer
WHERE customer_id = @p_customer_id

(affichez le champ customer_nm et l'utilisateur le modifie)

UPDATE demo_customer
SET customer_nm = @p_customer_name_new
WHERE customer_id = @p_customer_id
AND customer_name = @p_customer_nm_old

IF @@ROWCOUNT = 0
    RAISERROR( 'Update failed: Data changed' );

Vous n'avez pas besoin d'ajouter une nouvelle colonne à votre table (et de la maintenir à jour), mais vous devez créer des instructions SQL plus détaillées et passerNouveauetvieuxchamps à la procédure stockée.

Cela présente également l'avantage de ne pas verrouiller les enregistrements - car nous savons tous que les enregistrements finiront par rester verrouillés alors qu'ils ne devraient pas l'être ...

La source
Translate

La base de données le fera pour vous. Regardez "sélectionner ... pour la mise à jour", qui est conçu uniquement pour ce genre de chose. Cela vous donnera un verrou en écriture sur les lignes sélectionnées, que vous pourrez ensuite valider ou annuler.

La source
Translate

Avec moi, la meilleure façon d'avoir une colonne lastupdate (datatype d'horodatage). lors de la sélection et de la mise à jour, il suffit de comparer cette valeur, une autre avancée de cette solution est que vous pouvez utiliser cette colonne pour suivre le temps que les données ont changé. Je pense que ce n'est pas bon si vous créez simplement une colonne comme isLock pour la mise à jour des chèques.

La source