Technologieaustausch

Es gibt Thread-Sicherheitsprobleme in der Thread-Pool-Betriebsdatenbank

2024-07-12

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

Inhaltsverzeichnis

1. Einleitung

2. Frage

3. Lösung

3.1. Methode 1: Datenbankbeschränkungen

3.2. Methode 2: Verwenden Sie Sperren, um Threads einzuschränken

4. Zusammenfassung


1. Einleitung

Die aktuellen Anforderungen sind: Daten verarbeiten und in der Datenbank speichern. Während des Speichervorgangs wird zunächst abgefragt, ob die Daten in der Datenbank gespeichert wurden. Da die zu verarbeitenden Daten zu groß sind, ist ein Thread-Pool erforderlich zur gleichzeitigen Verarbeitung verwendet.

2. Frage

Beim Schreiben von Logik mit den oben genannten Methoden treten Thread-Sicherheitsprobleme auf: Einfügen während der Überprüfung (Problem der Dateninkonsistenz bei Datenbankabfragen), was zu wiederholtem Einfügen von Daten führt. Daher ist es notwendig, Maßnahmen zu ergreifen, um das Problem der Datenduplizierung zu begrenzen.

3. Lösung

3.1. Methode 1: Datenbankbeschränkungen

Entwerfen Sie ein Feld in der Datenbank als eindeutigen Index. Auch wenn der entsprechende Datensatz während der Abfrage nicht gefunden wird (tatsächlich bereits in der Datenbank vorhanden ist), wird beim Einfügen eine Fehlerausnahme für doppelte Felder gemeldet, die dazu führt, dass das Einfügen des Datensatzes fehlschlägt. Um das Problem der Deduplizierung zu lösen.

3.2. Methode 2: Verwenden Sie Sperren, um Threads einzuschränken

Wählen Sie eine geeignete Sperrstrategie basierend auf tatsächlichen Geschäftsszenarien. Optimistisches Sperren eignet sich für Szenarien mit weniger Schreibkonflikten und pessimistisches Sperren eignet sich für Szenarien mit mehr Schreibkonflikten.

Thread-Synchronisation: Verwenden Sie Synchronisationsmechanismen wie zReentrantLocksynchronized usw., um sicherzustellen, dass nur ein Thread gleichzeitig Abfrage- und Einfügevorgänge ausführen kann. Im Folgenden werden der Thread-Synchronisationsmechanismus und das Code-Anzeigedesign verwendet:

Mybatis-Schnittstellencode:

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

Erstellen Sie einen Serviceklassencode:

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

Das Obige ist nur ein kleiner Fall. Das tatsächliche Nutzungsszenario hängt von Ihren Anforderungen ab.Erklären Sie den obigen Code: usingUserService.class Als Sperrobjekt, um sicherzustellen, dass nur ein Thread gleichzeitig Abfrage- und Einfügevorgänge ausführen kann. Dies vermeidet Parallelitätsprobleme, kann jedoch zu Leistungsengpässen führen, insbesondere in Szenarien mit hoher Parallelität. Sie können die Verwendung feinkörnigerer Sperren oder Sperren auf Datenbankebene (z. B. pessimistische Sperren) in Betracht ziehen, um die Leistung zu optimieren.

4. Zusammenfassung

Die Logik der Thread-Pool-Betriebsdatenbank ist entsprechend den Anforderungen konzipiert, es gibt jedoch Thread-Sicherheitsprobleme im gesamten Prozess. Daher werden zwei Lösungen kurz vorgestellt: ① Festlegen eindeutiger Indexfelder in der Datenbanktabelle ② Verwenden von Sperren, um die Thread-Synchronisierung sicherzustellen. Wenn Sie es verwenden, passen Sie es an das tatsächliche Szenario an. Der Prozess ist relativ breit geschrieben und es werden nur zwei Methoden vorgestellt. Wenn Sie ihn genauer verstehen möchten, müssen Sie ihn weiter studieren. Ich hoffe natürlich, dass ich Dir durch meine kleinen Tipps eine kleine Antwort auf Deine Verwirrung geben kann.


Der Grund, warum Sie beim Lernen das Gefühl haben, zu schlafen, liegt darin, dass Träume dort beginnen.
ଘ(੭ˊᵕˋ)੭ (glücklich) ଘ(੭ˊᵕˋ)੭ (glücklich) ଘ(੭ˊᵕˋ)੭ (glücklich) ଘ(੭ˊᵕˋ)੭ (glücklich) ଘ(੭ˊᵕˋ)੭ (glücklich)
------Xiao Liu, der nicht herausragend sein wird, wenn er keinen Code schreibt