sql >> Database teknologi >  >> RDS >> Mysql

Hvordan bruger man transaktioner og låse korrekt for at sikre databaseintegritet?

Så langt så godt, dette vil i det mindste forhindre brugeren i at foretage checkout i flere sessioner (flere gange at prøve at betale det samme kort - godt at håndtere dobbeltklik.)

Hvordan tjekker du? Med en standard SELECT eller med en SELECT ... FOR UPDATE ? Baseret på trin 5 gætter jeg på, at du tjekker en reserveret kolonne på varen eller noget lignende.

Problemet her er, at SELECT ... FOR UPDATE i trin 2 vil IKKE anvende TIL OPDATERING lås til alt andet. Det gælder kun for det, der er SELECT ed:indkøbsvognen bord. Baseret på navnet vil det være en forskellig post for hver vogn/bruger. Det betyder, at andre transaktioner IKKE vil blive blokeret fra at fortsætte.

Efter ovenstående, baseret på de oplysninger, du har givet, kan du ende med, at flere personer køber den samme vare, hvis du ikke bruger VÆLG ... TIL OPDATERING på trin 3.

Foreslået løsning

  1. Begynd transaktionen
  2. VÆLG ... TIL OPDATERING indkøbsvognen tabel.

Dette vil låse et dobbeltklik fra at køre. Det, du vælger her, bør være en slags "vognbestilt" kolonne. Hvis du gør dette, vil en anden transaktion pause her og vente på, at den første er færdig, og derefter læse resultatet, hvad den først gemte i databasen.

Sørg for at afslutte betalingsprocessen her, hvis indkøbskurv-varen tabellen siger, at den allerede er bestilt.

  1. VÆLG ... TIL OPDATERING tabellen, hvor du registrerer, hvis en vare er blevet reserveret.

Dette vil låse ANDRE vogne/brugere fra at kunne læse disse varer.

Baseret på resultatet, hvis varerne ikke er reserveret, fortsæt:

  1. OPDATERING ... tabellen i trin 3, og markerer varen som reserveret. Gør en hvilken som helst anden INSERT s og OPDATERING s du også har brug for.

  2. Foretag betaling. Udsted en tilbagerulning, hvis betalingstjenesten siger, at betalingen ikke fungerede.

  3. Registrer betaling, hvis succes.

  4. Forpligt transaktion

Sørg for, at du ikke gør noget, der muligvis mislykkes mellem trin 5 og 7 (som at sende e-mails), ellers kan du ende med, at de foretager en betaling, uden at den bliver registreret, i tilfælde af at transaktionen bliver rullet tilbage.

Trin 3 er det vigtige skridt med hensyn til at sikre, at to (eller flere) personer ikke forsøger at bestille den samme vare. Hvis to personer prøver, vil den anden person ende med at få deres webside "hængt", mens den behandler den første. Når den første er færdig, vil den anden læse kolonnen "reserveret", og du kan returnere en besked til brugeren om, at nogen allerede har købt den vare.

Betaling i transaktion eller ej

Dette er subjektivt. Generelt vil du gerne lukke transaktioner så hurtigt som muligt for at undgå, at flere personer bliver låst ude fra at interagere med databasen på én gang.

Men i dette tilfælde vil du faktisk have dem til at vente. Det er bare et spørgsmål om hvor længe.

Hvis du vælger at forpligte transaktionen før betaling, skal du registrere dine fremskridt i en mellemliggende tabel, køre betalingen og derefter registrere resultatet. Vær opmærksom på, at hvis betalingen mislykkes, skal du manuelt fortryde de varereservationsregistreringer, som du opdaterede.

VÆLG ... TIL OPDATERING på ikke-eksisterende rækker

Bare en advarsel, hvis dit tabeldesign involverer indsættelse af rækker, hvor du skal tidligere VÆLG ... TIL OPDATERING :Hvis en række ikke eksisterer, vil den transaktion IKKE få andre transaktioner til at vente, hvis de også VÆLG ... TIL OPDATERING den samme ikke-eksisterende række.

Så sørg for altid at serialisere dine anmodninger ved at gøre en SELECT ... FOR UPDATE på en række, som du ved eksisterer først. Så kan du VÆLG ... TIL OPDATERING på rækken, der måske eller måske ikke eksisterer endnu. (Forsøg ikke kun at lave en SELECT på rækken, der måske eksisterer eller ikke eksisterer, da du vil læse rækkens tilstand på det tidspunkt, hvor transaktionen startede, ikke i det øjeblik, du kører SELECT . Så VÆLG ... TIL OPDATERING på ikke-eksisterende rækker er stadig noget, du skal gøre for at få den mest opdaterede information, bare vær opmærksom på, at det ikke vil få andre transaktioner til at vente.)



  1. Løsning af en kommunikationsforbindelsesfejl med JDBC og MySQL

  2. SQL Server 2016:Gem forespørgselsresultater til en CSV-fil

  3. Mysql-forespørgselsproblem

  4. Formål med at bruge forskellige typer PL/SQL-samlinger i Oracle