没有不值得去解决的问题,也没有不值得去学习的技术!

Prevent Duplicate Writes Under High Concurrency With Composite Unique Indexes on Windows 10, Yii2.0, and MySQL

The SQL statement executed successfully

1. In the production environment, duplicate data was written to the skill data table, as shown in Figure 1.

In the production environment, duplicate data was written to the skill data table
Figure 1

2. However, a check for whether the record already exists was performed before writing. The combination of game_code and team_code should be unique, as shown in Figure 2.

However, a check for whether the record already exists was performed before writing. The combination of game_code and team_code should be unique
Figure 2

3. I recommend first reviewing the URL: https://www.shuijingwanwq.com/2017/04/18/1568/ . Due to the mechanism of the program requested by POST, the ab POST file only supports parameters for a single request and cannot simulate the real scenario. In the real scenario, the parameters for each request would be different, so it is impossible to reproduce the production environment bug.

4. By commenting out the condition that checks whether the record exists, every request now inserts data, simulating a scenario where multiple skill records exist for a single match, as shown in Figure 3.

By commenting out the condition that checks whether the record exists, every request now inserts data, simulating a scenario where multiple skill records exist for a single match
Figure 3

5. Using Postman, I executed two consecutive requests with different parameters. Ultimately, 4 records existed in MySQL, as shown in Figures 4 and 5.

Using Postman, I executed two consecutive requests with different parameters
Figure 4
Ultimately, 4 records existed in MySQL
Figure 5

6. To prevent this situation, I decided to modify the table structure in MySQL. I deleted the 4 records from the table and added game_code and team_code as a composite unique index. In phpMyAdmin, I selected game_code and team_code, then clicked the Unique button, as shown in Figure 6.

Added game_code and team_code as a composite unique index. In phpMyAdmin, selected game_code and team_code, then clicked the Unique button
Figure 6

7. The SQL statement executed successfully, and the composite unique index was added successfully, as shown in Figures 7 and 8.

ALTER TABLE `kq_game_team_skill` ADD UNIQUE( `game_code`, `team_code`);

The SQL statement executed successfully
Figure 7
The composite unique index was added successfully
Figure 8

8. Using Gii, I regenerated the new model file, as shown in Figure 9.

Using Gii, regenerated the new model file
Figure 9

9. A new line was inserted into rules(), as shown in Figure 10.

A new line was inserted into rules()
Figure 10

10. Using Postman, I executed two consecutive requests with different parameters. An error occurred during the second execution, as shown in Figure 11.

Using Postman, I executed two consecutive requests with different parameters. An error occurred during the second execution
Figure 11

11. The error message had been processed. I printed the original error message, as shown in Figure 12.

The error message had been processed. I printed the original error message
Figure 12

12. The original error message: $gameTeamSkill->errors is as follows, as shown in Figure 13.

The original error message: $gameTeamSkill->errors is as follows
Figure 13

13. Checking MySQL at this point, there are only 2 skill data records corresponding to a match, and only 1 record per team, which meets expectations, as shown in Figure 14.

Checking MySQL at this point, there are only 2 skill data records corresponding to a match, and only 1 record per team, which meets expectations
Figure 14

14. Even though the ab stress test did not simulate the production environment bug, implementing the composite unique index in MySQL theoretically prevents this bug from recurring. However, the code returned is not a number, which needs further optimization.

关于作者 · 持续学习与技术实践

我是一名拥有 15 年以上开发经验的技术从业者,自 2013 年起持续运营个人技术博客,记录工作与个人项目中遇到的真实问题,以及解决问题过程中的探索、实践和思考。

除了技术写作,我也在持续开发和维护自己的独立项目,探索新技术和新工具在实际场景中的应用。我始终相信,没有不值得去解决的问题,也没有不值得去学习的技术。

如果这篇文章对你有所帮助,欢迎浏览博客中的其他文章,也欢迎交流技术经验与想法。

关于我  ·  GitHub  ·  邮件联系