Partage de technologie

Il existe des problèmes de sécurité des threads dans la base de données des opérations du pool de threads

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Table des matières

1. Introduction

2. Question

3. Solutions

3.1. Méthode 1 : Contraintes de la base de données

3.2 Méthode 2 : utiliser des verrous pour contraindre les threads

4. Résumé


1. Introduction

Les exigences actuelles sont les suivantes : traiter les données et stocker les données dans la base de données. Pendant le processus de stockage, il demandera d'abord si les données ont été stockées dans la base de données. Parce que les données à traiter sont trop volumineuses, un pool de threads doit être créé. utilisé pour le traitement simultané.

2. Question

Lors de l'écriture de la logique à l'aide des méthodes ci-dessus, il y aura des problèmes de sécurité des threads : insertion lors de la vérification (problème d'incohérence des données de requête de base de données), entraînant une insertion répétée de données. Il est donc nécessaire d’adopter des moyens pour limiter le problème de duplication des données.

3. Solutions

3.1. Méthode 1 : Contraintes de la base de données

Concevez un champ dans la base de données comme un index unique. Même si l'enregistrement de données correspondant n'est pas trouvé lors de la requête (il existe en fait déjà dans la base de données), une exception d'erreur de champ en double sera signalée lors de l'insertion, provoquant l'échec de l'insertion de l'enregistrement de données. Pour résoudre le problème de la déduplication.

3.2 Méthode 2 : utiliser des verrous pour contraindre les threads

Choisissez une stratégie de verrouillage appropriée en fonction de scénarios commerciaux réels. Le verrouillage optimiste convient aux scénarios comportant moins de conflits d'écriture, tandis que le verrouillage pessimiste convient aux scénarios comportant davantage de conflits d'écriture.

Synchronisation des threads : utilisez des mécanismes de synchronisation tels queReentrantLocksynchronized etc., pour garantir qu'un seul thread peut effectuer des opérations de requête et d'insertion en même temps. Ce qui suit utilise le mécanisme de synchronisation des threads et la conception d'affichage du code :

Code de l'interface mybatis :

  1. import org.apache.ibatis.annotations.*;
  2. public interface UserMapper {
  3. @Select("SELECT COUNT(*) FROM user WHERE username = #{username}")
  4. int countByUsername(@Param("username") String username);
  5. @Insert("INSERT INTO user (username, password, email) VALUES (#{username}, #{password}, #{email})")
  6. @Options(useGeneratedKeys = true, keyProperty = "id")
  7. int insertUser(User user);
  8. }

Créez le code de classe de service :

  1. import org.apache.ibatis.session.SqlSession;
  2. import org.apache.ibatis.session.SqlSessionFactory;
  3. import java.util.concurrent.ExecutorService;
  4. import java.util.concurrent.Executors;
  5. public class UserService {
  6. private final ExecutorService executorService;
  7. private final SqlSessionFactory sqlSessionFactory;
  8. public UserService(SqlSessionFactory sqlSessionFactory) {
  9. this.sqlSessionFactory = sqlSessionFactory;
  10. // 创建固定大小的线程池
  11. this.executorService = Executors.newFixedThreadPool(10);
  12. }
  13. public void addUser(User user) {
  14. executorService.submit(() -> {
  15. try (SqlSession session = sqlSessionFactory.openSession()) {
  16. UserMapper userMapper = session.getMapper(UserMapper.class);
  17. synchronized (UserService.class) {
  18. // 在同步块内执行查询和插入操作
  19. if (userMapper.countByUsername(user.getUsername()) == 0) {
  20. userMapper.insertUser(user);
  21. session.commit(); // 提交事务
  22. }
  23. }
  24. }
  25. });
  26. }
  27. }

Ce qui précède n'est qu'un petit cas, le scénario d'utilisation réel dépend de vos besoins.Expliquez le code ci-dessus : en utilisantUserService.class En tant qu'objet de verrouillage pour garantir qu'un seul thread peut effectuer des opérations de requête et d'insertion en même temps. Cela évite les problèmes de concurrence, mais peut entraîner des goulots d'étranglement en termes de performances, en particulier dans les scénarios à forte concurrence. Vous pouvez envisager d'utiliser des verrous plus fins ou des verrous au niveau de la base de données (tels que des verrous pessimistes) pour optimiser les performances.

4. Résumé

La logique de la base de données de fonctionnement du pool de threads est conçue en fonction des exigences, mais il existe des problèmes de sécurité des threads dans l'ensemble du processus. Par conséquent, deux solutions sont brièvement présentées : ① Définir des champs d'index uniques dans la table de la base de données ② Utiliser le verrouillage pour assurer la synchronisation des threads. Lorsque vous l'utilisez, ajustez-le en fonction du scénario réel. Le processus est écrit de manière relativement large et seules deux méthodes sont présentées. Si vous souhaitez le comprendre en profondeur, vous devez approfondir vos connaissances. Bien sûr, j'espère pouvoir vous apporter une petite réponse à votre confusion à travers mes petites astuces.


La raison pour laquelle vous avez envie de dormir lorsque vous étudiez est que c’est là que commencent les rêves.
ଘ(੭ˊᵕˋ)੭ (heureux) ଘ(੭ˊᵕˋ)੭ (heureux) ଘ(੭ˊᵕˋ)੭ (heureux) ଘ(੭ˊᵕˋ)੭ (heureux) ଘ(੭ˊᵕˋ)੭ (heureux)
------Xiao Liu, qui ne sera pas exceptionnel s'il n'écrit pas de code