Answer the question
In order to leave comments, you need to log in
How to avoid concurrent UPDATE of a MySQL database table?
I am developing a browser game that has a market. The market sells seeds and each user can put their seeds up for sale. There was a question of simultaneous use.
The table looks like this:
id | user_id | amount
1 | 4 | 0
2 | 1 | 30
3 | 5 | 10
1 user - SELECT * FROM market WHERE amount > 0 LIMIT 1
2 user - SELECT * FROM market WHERE amount > 0 LIMIT 1
1 user - UPDATE market SET amount = amount - 10 WHERE id LIKE id
1. Get the amount of the last record and set it to zero
2. Then update the amount (subtract purchased seeds) and update the record in the table (return unpurchased seeds)
Answer the question
In order to leave comments, you need to log in
Transactions are good for everyone, but under load they slow down the application and sometimes, if not properly handle requests to deadlocks.
You can create a separate table in which to record user requests for a resource, for example:
user ID, resource ID, application status (queued, processed, rejected), date and time of the application accurate to milliseconds (well, or a numeric field with auto-numbering).
When you click on "buy goods" the operation is performed in two steps, the first step is to place the user's request in this table. (several users can come for one resource and the one who came first will have priority)
The table is needed in order not to impose locks on the database tables (locks may be due to an open transaction)
Next, the second step is to launch the procedure for obtaining the status of the application (it should return a response whether the user received his resource or not, i.e. whether his application was processed successfully or rejected).
Request processing is a separate server process, it takes requests in order of receipt and processes (changes the state of the resource in the database and the state of the request) until the selected resource has enough quantity, all users who do not have enough resource receive a message about the impossibility to get the resource.
Read up on transactions, they lock fields while an UPDATE is in progress.
To buy, the user probably clicks on the button indicating the ID from the market table
So, at the time of purchase (before updating), do again select amount from market where id = 1)
and if amount > 0 then do an update, otherwise display to the user " sorry, someone already bought it
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question