Condivisione della tecnologia

Sono presenti problemi di sicurezza dei thread nel database delle operazioni del pool di thread

2024-07-12

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

Sommario

1. Introduzione

2. Domanda

3. Soluzione

3.1. Metodo 1: vincoli del database

3.2 Metodo 2: utilizzare i blocchi per vincolare i thread

4. Riepilogo


1. Introduzione

I requisiti attuali sono: elaborare i dati e archiviarli nel database Durante il processo di archiviazione, verrà innanzitutto verificata se i dati sono stati archiviati nel database. Poiché i dati da elaborare sono troppo grandi, è necessario che lo sia un pool di thread utilizzati per l'elaborazione simultanea.

2. Domanda

Quando si scrive la logica utilizzando i metodi sopra indicati, si verificheranno problemi di sicurezza del thread: inserimento durante il controllo (problema di incoerenza dei dati delle query del database), con conseguente inserimento ripetuto di dati. Pertanto è necessario adottare misure per limitare il problema della duplicazione dei dati.

3. Soluzione

3.1. Metodo 1: vincoli del database

Progettare un campo nel database come indice univoco Anche se il record di dati corrispondente non viene trovato durante la query (in realtà esiste già nel database), durante l'inserimento verrà segnalata un'eccezione di errore di campo duplicato, causando il fallimento dell'inserimento del record di dati. Per risolvere il problema della deduplicazione.

3.2 Metodo 2: utilizzare i blocchi per vincolare i thread

Scegli una strategia di blocco appropriata in base agli scenari aziendali reali. Il blocco ottimistico è adatto a scenari con meno conflitti di scrittura, mentre il blocco pessimistico è adatto a scenari con più conflitti di scrittura.

Sincronizzazione dei thread: utilizzare meccanismi di sincronizzazione comeReentrantLocksynchronized ecc., per garantire che solo un thread possa eseguire operazioni di query e inserimento contemporaneamente. Di seguito viene utilizzato il meccanismo di sincronizzazione dei thread e la progettazione della visualizzazione del codice:

codice interfaccia 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. }

Crea il codice della classe di servizio:

  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. }

Quanto sopra è solo un piccolo caso, lo scenario di utilizzo effettivo dipende dalle tue esigenze.Spiegare il codice precedente: usingUserService.class Come oggetto di blocco per garantire che solo un thread possa eseguire operazioni di query e inserimento contemporaneamente. Ciò evita problemi di concorrenza, ma può causare colli di bottiglia nelle prestazioni, soprattutto in scenari con elevata concorrenza. Puoi prendere in considerazione l'utilizzo di blocchi più dettagliati o blocchi a livello di database (come i blocchi pessimistici) per ottimizzare le prestazioni.

4. Riepilogo

La logica del database delle operazioni del pool di thread è progettata in base ai requisiti, ma sono presenti problemi di sicurezza dei thread nell'intero processo. Pertanto, vengono brevemente introdotte due soluzioni: ① Impostazione di campi indice univoci nella tabella del database ② Utilizzo del blocco per garantire la sincronizzazione dei thread. Quando lo usi, adattalo in base allo scenario reale. Il processo è scritto in modo relativamente ampio e vengono introdotti solo due metodi. Se vuoi capirlo in profondità, devi studiare ulteriormente. Naturalmente spero di poterti dare una piccola risposta alla tua confusione attraverso i miei piccoli consigli.


Il motivo per cui hai voglia di dormire mentre studi è perché è lì che iniziano i sogni.
ଘ(੭ˊᵕˋ)੭ (felice) ଘ(੭ˊᵕˋ)੭ (felice) ଘ(੭ˊᵕˋ)੭ (felice) ଘ(੭ˊᵕˋ)੭ (felice) ଘ(੭ˊᵕˋ)੭ (felice)
------Xiao Liu, che non sarà eccezionale se non scrive codice