sql >> Databasteknik >  >> RDS >> Mysql

Hur använder man transaktioner och lås korrekt för att säkerställa databasens integritet?

Så långt så bra, detta kommer åtminstone att förhindra att användaren gör kassan i flera sessioner (flera gånger försöker kassan samma kort - bra att hantera dubbelklick.)

Hur kollar man? Med en standard SELECT eller med en SELECT ... FOR UPDATE ? Baserat på steg 5 gissar jag att du markerar en reserverad kolumn på objektet, eller något liknande.

Problemet här är att SELECT ... FOR UPDATE i steg 2 kommer INTE att tillämpa FOR UPDATE lås till allt annat. Det gäller bara det som är SELECT ed:cart-item tabell. Baserat på namnet kommer det att bli en annan post för varje vagn/användare. Detta innebär att andra transaktioner INTE kommer att blockeras från att fortsätta.

Efter ovanstående, baserat på informationen du har angett, kan du sluta med att flera personer köper samma vara, om du inte använder SELECT ... FOR UPDATE på steg 3.

Föreslagen lösning

  1. Börja transaktionen
  2. SELECT ... FOR UPDATE cart-item tabell.

Detta kommer att låsa ett dubbelklick från att köras. Det du väljer här bör vara någon sorts "vagnbeställd" kolumn. Om du gör detta kommer en andra transaktion att pausa här och vänta på att den första ska slutföras och sedan läsa resultatet vad den första sparade i databasen.

Se till att avsluta utcheckningsprocessen här om cart-item tabellen säger att den redan har beställts.

  1. SELECT ... FOR UPDATE tabellen där du registrerar om ett objekt har reserverats.

Detta kommer att låsa ANDRA vagnar/användare från att kunna läsa dessa föremål.

Baserat på resultatet, om objekten inte är reserverade, fortsätt:

  1. UPDATE ... tabellen i steg 3, markera objektet som reserverat. Gör någon annan INSERT s och UPDATE du behöver också.

  2. Betala. Utfärda en återställning om betaltjänsten säger att betalningen inte fungerade.

  3. Registrera betalningen, om den lyckas.

  4. Bekräfta transaktion

Se till att du inte gör något som kan misslyckas mellan steg 5 och 7 (som att skicka e-post), annars kan du sluta med att de gör en betalning utan att den registreras, i händelse av att transaktionen återställs.

Steg 3 är det viktiga steget när det gäller att se till att två (eller fler) personer inte försöker beställa samma vara. Om två personer försöker, kommer den andra personen att få sin webbsida att "hänga sig" medan den bearbetar den första. När den första är klar kommer den andra att läsa kolumnen "reserverad" och du kan skicka ett meddelande till användaren om att någon redan har köpt den artikeln.

Betalning i transaktion eller inte

Detta är subjektivt. I allmänhet vill du stänga transaktioner så snabbt som möjligt för att undvika att flera personer låses ute från att interagera med databasen samtidigt.

Men i det här fallet vill du faktiskt att de ska vänta. Det är bara en fråga om hur länge.

Om du väljer att genomföra transaktionen före betalning, måste du registrera dina framsteg i någon mellantabell, köra betalningen och sedan registrera resultatet. Tänk på att om betalningen misslyckas måste du manuellt ångra objektreservationsposterna som du uppdaterade.

VÄLJ ... FÖR UPPDATERING på obefintliga rader

Bara ett ord av varning, ifall din tabelldesign innebär att du infogar rader där du behöver tidigare SELECT ... FOR UPDATE :Om en rad inte finns kommer den transaktionen INTE att få andra transaktioner att vänta, om de också SELECT ... FOR UPDATE samma obefintliga rad.

Så se till att alltid serialisera dina förfrågningar genom att göra en SELECT ... FOR UPDATE på en rad som du vet finns först. Sedan kan du SELECT ... FOR UPDATE på raden som kanske eller kanske inte finns ännu. (Försök inte att bara göra en SELECT på raden som kanske finns eller inte finns, eftersom du kommer att läsa radens tillstånd när transaktionen startade, inte i det ögonblick du kör SELECT . Så, SELECT ... FOR UPDATE på obefintliga rader är fortfarande något du behöver göra för att få den mest uppdaterade informationen, var bara medveten om att det inte kommer att få andra transaktioner att vänta.)



  1. Hur man tar bort text mellan 2 tecken med query i MYSQL

  2. PHP - MySQL får värdet av ut parameter från en lagrad procedur

  3. Hur man installerar MySQL på macOS

  4. Hur man hittar waitevent History of the Oracle-session