Redigering databaseposter ved flere brukere

stemmer
24

Jeg har utviklet databasetabeller (normaliserte, på en MS SQL server) og opprettet en frittstående Windows-grensesnitt for et program som vil bli brukt av en håndfull brukere å legge til og redigere informasjon. Vi vil legge til et web-grensesnitt for å tillate søker tvers våre produksjonsområde på et senere tidspunkt.

Jeg er bekymret for at hvis to brukere å redigere den samme posten da den siste til å begå oppdateringen vil være 'vinneren' og viktig informasjon kan gå tapt. En rekke løsninger kommer til tankene, men jeg er ikke sikker på om jeg kommer til å skape en større hodepine.

  1. Gjør ingenting og håper at to brukere aldri kommer til å bli redigere samme posten på samme tid. - Kan aldri happed men hva hvis den gjør det?
  2. Redigerer rutine kan lagre en kopi av de opprinnelige dataene samt oppdateringer og deretter sammenligne når brukeren er ferdig redigering. Hvis de skiller showet brukeren og comfirm oppdatering - Vil kreve to kopier av data som skal lagres.
  3. Legg Sist oppdatert DATETIME kolonne og sjekke det stemmer når vi oppdaterer, hvis ikke så viser forskjeller. - krever ny kolonne i hver av de aktuelle tabellene.
  4. Lag en redigering tabell som registrerer når brukere begynne å redigere en rekord som vil bli sjekket og hindre andre brukere fra å redigere samme posten. - ville kreve carful tanken på programflyten for å hindre vranglåser og poster blir låst hvis en bruker krasjer ut av programmet.

Er det noen bedre løsninger eller bør jeg gå for en av disse?

Publisert på 03/08/2008 klokken 21:23
kilden bruker
På andre språk...                            


8 svar

stemmer
13

Hvis du forventer sjeldne kollisjoner, Optimistisk Samtidighet er trolig det beste alternativet.

Scott Mitchell skrev en omfattende tutorial på å implementere dette mønsteret:
Implementering optimistisk concurrency

Svarte 03/08/2008 kl. 21:31
kilden bruker

stemmer
2

En klassisk tilnærming er som følger:

  • legge til en boolsk felt, "låst" til hvert bord.
  • sett denne til false som standard.
  • når en bruker starter redigering, gjør du dette:

    • låse rad (eller hele tabellen hvis du ikke kan låse rad)
    • sjekk flagget på raden du vil redigere
    • om flagget er sant da
      • informere brukeren om at de ikke kan redigere den raden i øyeblikket
    • ellers
      • satt flagget til sann
    • frigjøre låsen

    • når du lagrer posten, sette flagget tilbake til false

Svarte 01/10/2008 kl. 08:53
kilden bruker

stemmer
1

-first skape arkivert (oppdatering tid) til å lagre siste oppdatering posten -Når alle brukere velge posten spare velg tid, sammenligne mellom utvalg tid og oppdatere tidsfeltet if (oppdatering tid)> (velg tid) det at en annen bruker oppdatering denne posten etter velger ta opp

Svarte 14/07/2016 kl. 11:23
kilden bruker

stemmer
1

SELECT FOR UPDATE og ekvivalenter er bra å tilby du holder låsen for en mikroskopisk mengde tid, men for en makroskopisk beløp (f.eks brukeren har dataene lastet og har ikke trykket 'lagre' du bør bruke optimistisk concurrency som ovenfor. (Som jeg tenker alltid er misnamed - det er mer pessimistiske enn 'forrige skribent vinner', som vanligvis er den eneste andre alternativet vurderes).

Svarte 01/10/2008 kl. 05:39
kilden bruker

stemmer
1

Et annet alternativ er å teste at verdiene i posten som du endrer er fortsatt de samme som de var da du startet:

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

(Vise customer_nm felt og brukeren endrer den)

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' );

Du trenger ikke å legge til en ny kolonne i tabellen (og holde det oppdatert), men du trenger ikke å skape mer utførlige SQL-setninger og passere nye og gamle felt til den lagrede prosedyren.

Det har også den fordelen at du ikke låser postene - fordi vi alle vet at postene vil ende opp med å bo låst når de ikke skal være ...

Svarte 13/08/2008 kl. 22:32
kilden bruker

stemmer
1

@ Mark Harrison: SQL Server støtter ikke at syntaks ( SELECT ... FOR UPDATE).

SQL Server tilsvarende er SELECTutsagnet hint UPDLOCK.

Se SQL Server Books Online for mer informasjon.

Svarte 04/08/2008 kl. 21:54
kilden bruker

stemmer
0

Med meg er den beste måten jeg har en kolonne LASTUPDATE (timetamp datatype). da velger og oppdatering bare sammenligne denne verdien annen forkant av denne løsningen er at du kan bruke denne kolonnen til å spore opp den tiden data har endring. Jeg tror det er ikke bra hvis du bare lage en colum som isLock for sjekk oppdatering.

Svarte 24/06/2011 kl. 07:14
kilden bruker

stemmer
0

Databasen vil gjøre dette for deg. Se på "velg ... for oppdatering", som er laget nettopp for denne type ting. Det vil gi deg en skrive lås på de valgte radene, som du deretter kan forplikte eller rulle tilbake.

Svarte 04/08/2008 kl. 02:30
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more