Project

General

Profile

Test.java

Artur Școlnic, 03/27/2026 05:54 AM

Download (4.09 KB)

 
1
import java.sql.*;
2
import java.util.Random;
3
import java.util.concurrent.CountDownLatch;
4
import java.util.concurrent.ExecutorService;
5
import java.util.concurrent.Executors;
6

    
7
public class Test {
8

    
9
   private static final String URL = "jdbc:h2:mem:testdb;db_close_delay=-1;mv_store=true;rtrim=true;default_ignore_case=true;LOCK_TIMEOUT=1000";
10

    
11
   public static void main(String[] args) throws Exception {
12

    
13
      // Step 1: Create table
14
      try (Connection conn = DriverManager.getConnection(URL, "sa", "")) {
15
         conn.createStatement().execute(
16
                 "CREATE TABLE meta_connect (" +
17
                 "id BIGINT PRIMARY KEY, " +
18
                 "connect_usr INT, " +
19
                 "connect_name VARCHAR(255))"
20
         );
21
         System.out.println("Table created.");
22
      }
23

    
24
      int threadCount = 20000;
25
      Random random = new Random();
26
      ExecutorService executor = Executors.newFixedThreadPool(threadCount);
27
      CountDownLatch latch = new CountDownLatch(threadCount);
28

    
29
      for (int i = 0; i < threadCount; i++) {
30
         final int threadId = i;
31

    
32
         executor.submit(() -> {
33
            Connection conn = null;
34

    
35
            try {
36
               conn = DriverManager.getConnection(URL, "sa", "");
37
               conn.setAutoCommit(false);
38

    
39
               long newId = System.nanoTime();
40
               int connectUsr = 42; // same user for concurrency
41
               String name = "User-" + threadId;
42

    
43
               if (random.nextBoolean()) {
44
                  // 50% chance: MERGE (insert or update existing id)
45
                  PreparedStatement merge = conn.prepareStatement(
46
                          "MERGE INTO meta_connect (id, connect_usr, connect_name) KEY(id) VALUES (?, ?, ?)"
47
                  );
48
                  merge.setLong(1, newId); // new row
49
                  merge.setInt(2, connectUsr);
50
                  merge.setString(3, name);
51
                  merge.executeUpdate();
52
               } else {
53
                  // 50% chance: update an existing row if any
54
                  PreparedStatement select = conn.prepareStatement(
55
                          "SELECT id FROM meta_connect WHERE connect_usr = ? LIMIT 1"
56
                  );
57
                  select.setInt(1, connectUsr);
58
                  ResultSet rs = select.executeQuery();
59

    
60
                  if (rs.next()) {
61
                     long existingId = rs.getLong(1);
62
                     PreparedStatement update = conn.prepareStatement(
63
                             "UPDATE meta_connect SET connect_name = ? WHERE id = ?"
64
                     );
65
                     update.setString(1, name + "-upd");
66
                     update.setLong(2, existingId);
67
                     update.executeUpdate();
68
                  } else {
69
                     // fallback: insert new row
70
                     PreparedStatement insert = conn.prepareStatement(
71
                             "INSERT INTO meta_connect (id, connect_usr, connect_name) VALUES (?, ?, ?)"
72
                     );
73
                     insert.setLong(1, newId);
74
                     insert.setInt(2, connectUsr);
75
                     insert.setString(3, name);
76
                     insert.executeUpdate();
77
                  }
78
               }
79

    
80
               conn.commit();
81

    
82
            } catch (Exception e) {
83
               System.err.println("Thread " + threadId + " FAILED: " + e.getMessage());
84
               try {
85
                  if (conn != null) conn.rollback();
86
               } catch (Exception ignored) {}
87
            } finally {
88
               latch.countDown();
89
               try {
90
                  if (conn != null) conn.close();
91
               } catch (Exception ignored) {}
92
            }
93
         });
94
      }
95

    
96
      latch.await();
97
      executor.shutdown();
98

    
99
      System.out.println("\nAll threads finished.\n");
100

    
101
      // Step 3: Verify result
102
      try (Connection conn = DriverManager.getConnection(URL, "sa", "")) {
103
         ResultSet rs1 = conn.createStatement()
104
                             .executeQuery("SELECT COUNT(*) FROM meta_connect");
105
         rs1.next();
106
         int totalRows = rs1.getInt(1);
107

    
108
         System.out.println("Total rows: " + totalRows);
109
      }
110
   }
111
}