001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (license2)
004: * Initial Developer: H2 Group
005: */
006: package org.h2.test.synth;
007:
008: import java.sql.Connection;
009: import java.sql.PreparedStatement;
010: import java.sql.ResultSet;
011: import java.sql.Statement;
012: import java.util.Random;
013:
014: import org.h2.test.TestBase;
015:
016: /**
017: * This test starts multiple threads and executes random operations in each
018: * thread.
019: */
020: public class TestThreads extends TestBase implements Runnable {
021:
022: public TestThreads() {
023: }
024:
025: public void test() throws Exception {
026: deleteDb("threads");
027: Connection conn = getConnection("threads;MAX_LOG_SIZE=1");
028: Statement stat = conn.createStatement();
029: stat
030: .execute("CREATE TABLE TEST_A(ID INT PRIMARY KEY, NAME VARCHAR)");
031: stat
032: .execute("CREATE TABLE TEST_B(ID INT PRIMARY KEY, NAME VARCHAR)");
033: stat
034: .execute("CREATE TABLE TEST_C(ID INT PRIMARY KEY, NAME VARCHAR)");
035: int len = 1000;
036: insertRows(conn, "TEST_A", len);
037: insertRows(conn, "TEST_B", len);
038: insertRows(conn, "TEST_C", len);
039: maxId = len;
040: int threadCount = 4;
041: Thread[] threads = new Thread[threadCount];
042: for (int i = 0; i < threadCount; i++) {
043: String table = random.nextBoolean() ? null
044: : getRandomTable();
045: int op = random.nextInt(OP_TYPES);
046: op = i % 2 == 1 ? RECONNECT : CHECKPOINT;
047: threads[i] = new Thread(new TestThreads(this , op, table));
048: }
049: for (int i = 0; i < threadCount; i++) {
050: threads[i].start();
051: }
052: Thread.sleep(10000);
053: stop = true;
054: for (int i = 0; i < threadCount; i++) {
055: threads[i].join();
056: }
057: conn.close();
058: conn = getConnection("threads");
059: checkTable(conn, "TEST_A");
060: checkTable(conn, "TEST_B");
061: checkTable(conn, "TEST_C");
062: conn.close();
063: }
064:
065: private void insertRows(Connection conn, String tableName, int len)
066: throws Exception {
067: PreparedStatement prep = conn.prepareStatement("INSERT INTO "
068: + tableName + " VALUES(?, 'Hi')");
069: for (int i = 0; i < len; i++) {
070: prep.setInt(1, i);
071: prep.execute();
072: }
073: }
074:
075: private void checkTable(Connection conn, String tableName)
076: throws Exception {
077: Statement stat = conn.createStatement();
078: ResultSet rs = stat.executeQuery("SELECT * FROM " + tableName
079: + " ORDER BY ID");
080: while (rs.next()) {
081: int id = rs.getInt(1);
082: String name = rs.getString(2);
083: System.out.println("id=" + id + " name=" + name);
084: }
085: }
086:
087: private int maxId = 1;
088:
089: private volatile boolean stop;
090: private TestThreads master;
091: private int type;
092: private String table;
093: private Random random = new Random();
094:
095: private static final int INSERT = 0, UPDATE = 1, DELETE = 2;
096: private static final int SELECT_ONE = 3, SELECT_ALL = 4,
097: CHECKPOINT = 5, RECONNECT = 6;
098: private static final int OP_TYPES = RECONNECT + 1;
099:
100: private int getMaxId() {
101: return maxId;
102: }
103:
104: private synchronized int incrementMaxId() {
105: return maxId++;
106: }
107:
108: TestThreads(TestThreads master, int type, String table) {
109: this .master = master;
110: this .type = type;
111: this .table = table;
112: }
113:
114: private String getRandomTable() {
115: return "TEST_" + (char) ('A' + random.nextInt(3));
116: }
117:
118: public void run() {
119: try {
120: String t = table == null ? getRandomTable() : table;
121: Connection conn = master.getConnection("threads");
122: Statement stat = conn.createStatement();
123: ResultSet rs;
124: int max = master.getMaxId();
125: int rid = random.nextInt(max);
126: for (int i = 0; !master.stop; i++) {
127: switch (type) {
128: case INSERT:
129: max = master.incrementMaxId();
130: stat
131: .execute("INSERT INTO " + t
132: + "(ID, NAME) VALUES(" + max
133: + ", 'Hello')");
134: break;
135: case UPDATE:
136: stat.execute("UPDATE " + t + " SET NAME='World "
137: + rid + "' WHERE ID=" + rid);
138: break;
139: case DELETE:
140: stat.execute("DELETE FROM " + t + " WHERE ID="
141: + rid);
142: break;
143: case SELECT_ALL:
144: rs = stat.executeQuery("SELECT * FROM " + t
145: + " ORDER BY ID");
146: while (rs.next()) {
147: // nothing
148: }
149: break;
150: case SELECT_ONE:
151: rs = stat.executeQuery("SELECT * FROM " + t
152: + " WHERE ID=" + rid);
153: while (rs.next()) {
154: // nothing
155: }
156: break;
157: case CHECKPOINT:
158: stat.execute("CHECKPOINT");
159: break;
160: case RECONNECT:
161: conn.close();
162: conn = master.getConnection("threads");
163: break;
164: }
165: }
166: conn.close();
167: } catch (Exception e) {
168: TestBase.logError("error", e);
169: }
170: }
171:
172: }
|