|
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
|
|
|
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;
|
|
41
|
String name = "User-" + threadId;
|
|
42
|
|
|
43
|
if (random.nextBoolean()) {
|
|
44
|
|
|
45
|
PreparedStatement merge = conn.prepareStatement(
|
|
46
|
"MERGE INTO meta_connect (id, connect_usr, connect_name) KEY(id) VALUES (?, ?, ?)"
|
|
47
|
);
|
|
48
|
merge.setLong(1, newId);
|
|
49
|
merge.setInt(2, connectUsr);
|
|
50
|
merge.setString(3, name);
|
|
51
|
merge.executeUpdate();
|
|
52
|
} else {
|
|
53
|
|
|
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
|
|
|
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
|
|
|
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
|
}
|