Data error occurred when the mysql database is modified concurrently

Problem phenomenon
H5 game, online users report a bug saying that the account balance information does not match the transaction flow. It can be considered as a problem of concurrent update of the database, so as to locate the specific cause and give a solution.

Scenario description
When the background recharges or withdraws cash for the user, and in the case of high concurrency, there is a recharge of 100 yuan (assuming that the current user balance is 50 yuan) and at the same time the user bets 10 yuan. At this time, it is used to generate two account changes Information, the result should be
1 change amount 10 change balance 40 content "bet"
2 change amount 100 change balance 140 content "recharge"
or
1 change amount 100 change balance 150 content "recharge"
2 change amount 10 change balance 140 content "bet"
but
the account change information table shows
1 changed amount 100 changed balance 150 content "recharge"
2 changed amount 10 changed balance 40 content "bet" here should be changed balance 140 after
the user changes Incorrect balance.
Environment description
mysql5.6 + innodb + php5.6
scenario simulation
The specific operation is
select money from user where id=x;
update usercoinlog set bdmoney = just found balance + change amount WHERE userid=x;

The problem occurred.
Cause location
If the background recharge and user bet are carried out at the same time, the balance found at the same time is 50, and the above error will occur when 50 is used as a reference record when updating!

Solution
Option 1
Increase the database lock, but this thing has certain disadvantages, and I will introduce it later

Solution 2:
Take out a field value when querying, such as the number of updates. When updating, I update the table set Money=Money-50, update times=update times+1 where userid=123 and update times=just queried The number of times, for example, the results of two queries sent concurrently are 50, but there is always a sequence of execution updates. At this time, the number of updates of Money-50 is also +1 at the same time. The second update operation finds that the number of updates is not equal to the number of times just queried , update invalid

This problem is solved perfectly!

extended thinking

The update problem is the same, but the insertion problem remains the same.

solve

Each person is only allowed to have one record in each issue. The issue number is unique to each person, but it is not unique to everyone. +id is the unique value of each person in the current period. You can create a new field and write the current issue number +id into it when writing. If the value of this field exists during high-concurrency writing, the writing will fail. An exception is thrown, and the update operation is performed. You can also combine multiple columns to be unique, so you don't need to add more unique fields!

Some personal humble opinion: Welcome to Paizhuan!_Welcome to correct mistakes

Guess you like

Origin blog.csdn.net/Sncdma/article/details/107853524
Recommended