MySQL probleem bij 'lag'

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hallo,

Ik ben tegen een probleem aangelopen, ik zal het even kort uitleggen.

gebruikersnaam | 25 punten
gebruikersnaam2 | 15 punten

Met een bepaalde functie binnen het platform 'steel' ik punten van de andere gebruikersnaam.
Maar als het systeem druk is, of het in een heel rap tempo gebeurd (flooding) dan kan gebruikersnaam2 in de - komen met punten en die komen wel bij de ander. Al met al komen er dus punten die niet in het platform actief zijn.

Ik gebruik hiervoor gewoon twee SQL queries;
UPDATE table SET punten=punten-aantal WHERE userid=A
UPDATE table SET punten=punten+aantal WHERE userid=B

Als opslag engine word er InnoDB gebruikt.
Wat kan ik hier tegen doen, zodat het niet kan voorkomen? Een aanpassing in de queries, of iets doen met locking? (geen ervaring mee).

Alvast bedankt!

Acties:
  • 0 Henk 'm!

  • SoulWar1
  • Registratie: Augustus 2004
  • Laatst online: 18-09 22:27
Ik zou eerst controleren of de gebruiker wel genoeg punten heeft om af te schrijven en vervolgens alle mutaties in een transactie doorvoeren.

Know Thyself


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Zou dan een simpele check als;

puntennu - aantal dat eraf gaat voldoende zijn, indien > 0 eraf halen en anders een foutmelding? Of moet dit echt met een wat 'betere' check?

Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Verwijderd schreef op donderdag 28 oktober 2010 @ 21:14:
puntennu - aantal dat eraf gaat voldoende zijn, indien > 0 eraf halen en anders een foutmelding? Of moet dit echt met een wat 'betere' check?
Dat laatste, en het zoekwoord is transacties. Je moet wel InnoDB gebruiken daarvoor.

Acties:
  • 0 Henk 'm!

  • KoenBud
  • Registratie: Oktober 2010
  • Laatst online: 18-09 16:46
Dan kan door de eerste query beginnen met START TRANSACTION en na de laatste query eindigen met COMMIT.

Google ook eens op ACID.

Edit: Ik zou mij wel even inlezen in wat transacties precies doen voordat je dit gaat gebruiken. Er kunnen best nog andere bijwerkingen zijn.

[ Voor 36% gewijzigd door KoenBud op 28-10-2010 21:24 ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 21-09 02:21

Janoz

Moderator Devschuur®

!litemod

Transacties zijn helemaal niet nodig. De enige manier hoe iemand in de min kan komen is door 1 atomaire actie. Wanneer die gelukt is, maakt het niet meer uit wanneer de punten bij de andere gebruiker opgeteld worden. Die kan met die actie immers nooit in de min komen.

De oplossing is redelijk simpel.Verander je eerste update statement in:
UPDATE table SET punten = punten - aantal WHERE gebruiker = a and punten >= aantal

Vervolgens kun je met affected rows zien of de update gelukt is en of je dus de punten bij gebruiker 2 op kunt tellen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • kunnen
  • Registratie: Februari 2004
  • Niet online
Transactions gaan je hier uberhaubt niet helpen met de huidige queries (immers de updates zijn atomair; je wilt juist atomair controleren en updaten). Janoz heeft de enige juiste oplossing.

Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Transacties werken op zich wel: je doet een rollback van increment als de decrement AffectedRows=0 oplevert. Maar zoals Janoz al uitlegde: wissel de volgorde om, en dan hoef je de increment niet eens te doen als de decrement mislukt.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

  • bomberboy
  • Registratie: Mei 2007
  • Laatst online: 21-09 18:26

bomberboy

BOEM!

Maar indien je increment mislukt (en de decrement is dus eerst wel gelukt) dan heb je alsnog een probleem omdat er punten gaan verdwijnen uit het systeem. Daarvoor heb je die transactie net wel nodig natuurlijk.

Het zal misschien in praktijk zelden of nooit voorkomen, maar het moment dat je er op vertrouwt dat het nooit voorkomt zal het wel eens mislopen (en ga dan maar debuggen).

Er kunnen immers altijd externe oorzaken zijn waardoor een query faalt

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Janoz schreef op donderdag 28 oktober 2010 @ 21:50:
Transacties zijn helemaal niet nodig. De enige manier hoe iemand in de min kan komen is door 1 atomaire actie. Wanneer die gelukt is, maakt het niet meer uit wanneer de punten bij de andere gebruiker opgeteld worden. Die kan met die actie immers nooit in de min komen.

De oplossing is redelijk simpel.Verander je eerste update statement in:
UPDATE table SET punten = punten - aantal WHERE gebruiker = a and punten >= aantal

Vervolgens kun je met affected rows zien of de update gelukt is en of je dus de punten bij gebruiker 2 op kunt tellen.
Ik ga dit toepassen, en zal testen of het werkt en hier later nogmaals op terug komen.
Bedankt allemaal, voor het mee-denken!

-
De aanpassing heeft effect, het is niet meer mogelijk! Bedankt!

[ Voor 4% gewijzigd door Verwijderd op 30-10-2010 15:11 ]

Pagina: 1