Source code: org/hsqldb/test/JDBCBench.java
1 /* Copyright (c) 2001-2002, The HSQL Development Group
2 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of the HSQL Development Group nor the names of its
15 * contributors may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
22 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31
32 package org.hsqldb.test;
33
34 /*
35 * This is a sample implementation of the Transaction Processing Performance
36 * Council Benchmark B coded in Java and ANSI SQL2.
37 *
38 * This version is using one connection per thread to parallellize
39 * server operations.
40 */
41 import java.sql.*;
42 import java.util.*;
43 import java.io.*;
44
45 class JDBCBench {
46
47 /* tpc bm b scaling rules */
48 public static int tps = 1; /* the tps scaling factor: here it is 1 */
49 public static int nbranches = 1; /* number of branches in 1 tps db */
50 public static int ntellers = 10; /* number of tellers in 1 tps db */
51 public static int naccounts = 100000; /* number of accounts in 1 tps db */
52 public static int nhistory = 864000; /* number of history recs in 1 tps db */
53 public final static int TELLER = 0;
54 public final static int BRANCH = 1;
55 public final static int ACCOUNT = 2;
56 int failed_transactions = 0;
57 int transaction_count = 0;
58 static int n_clients = 10;
59 static int n_txn_per_client = 10;
60 long start_time = 0;
61 static boolean transactions = true;
62 static boolean prepared_stmt = false;
63 static String tableExtension = "";
64 static String createExtension = "";
65 static String ShutdownCommand = "";
66 static PrintStream TabFile = null;
67 static boolean verbose = false;
68 MemoryWatcherThread MemoryWatcher;
69
70 /* main program, creates a 1-tps database: i.e. 1 branch, 10 tellers,...
71 * runs one TPC BM B transaction
72 * example command line:
73 * -driver org.hsqldb.jdbcDriver -url jdbc:hsqldb:/hsql/test33 -user sa -clients 20
74 */
75 public static void main(String[] Args) {
76
77 String DriverName = "";
78 String DBUrl = "";
79 String DBUser = "";
80 String DBPassword = "";
81 boolean initialize_dataset = false;
82
83 for (int i = 0; i < Args.length; i++) {
84 if (Args[i].equals("-clients")) {
85 if (i + 1 < Args.length) {
86 i++;
87
88 n_clients = Integer.parseInt(Args[i]);
89 }
90 } else if (Args[i].equals("-driver")) {
91 if (i + 1 < Args.length) {
92 i++;
93
94 DriverName = Args[i];
95
96 if (DriverName.equals(
97 "org.enhydra.instantdb.jdbc.idbDriver")) {
98 ShutdownCommand = "SHUTDOWN";
99 }
100
101 if (DriverName.equals(
102 "com.borland.datastore.jdbc.DataStoreDriver")) {}
103
104 if (DriverName.equals("com.mckoi.JDBCDriver")) {
105 ShutdownCommand = "SHUTDOWN";
106 }
107
108 if (DriverName.equals("org.hsqldb.jdbcDriver")) {
109 tableExtension = "CREATE CACHED TABLE ";
110 ShutdownCommand = "SHUTDOWN COMPACT";
111 }
112 }
113 } else if (Args[i].equals("-url")) {
114 if (i + 1 < Args.length) {
115 i++;
116
117 DBUrl = Args[i];
118 }
119 } else if (Args[i].equals("-user")) {
120 if (i + 1 < Args.length) {
121 i++;
122
123 DBUser = Args[i];
124 }
125 } else if (Args[i].equals("-tabfile")) {
126 if (i + 1 < Args.length) {
127 i++;
128
129 try {
130 FileOutputStream File = new FileOutputStream(Args[i]);
131
132 TabFile = new PrintStream(File);
133 } catch (Exception e) {
134 TabFile = null;
135 }
136 }
137 } else if (Args[i].equals("-password")) {
138 if (i + 1 < Args.length) {
139 i++;
140
141 DBPassword = Args[i];
142 }
143 } else if (Args[i].equals("-tpc")) {
144 if (i + 1 < Args.length) {
145 i++;
146
147 n_txn_per_client = Integer.parseInt(Args[i]);
148 }
149 } else if (Args[i].equals("-init")) {
150 initialize_dataset = true;
151 } else if (Args[i].equals("-tps")) {
152 if (i + 1 < Args.length) {
153 i++;
154
155 tps = Integer.parseInt(Args[i]);
156 }
157 } else if (Args[i].equals("-v")) {
158 verbose = true;
159 }
160 }
161
162 if (DriverName.length() == 0 || DBUrl.length() == 0) {
163 System.out.println(
164 "usage: java JDBCBench -driver [driver_class_name] -url [url_to_db] -user [username] -password [password] [-v] [-init] [-tpc n] [-clients]");
165 System.out.println();
166 System.out.println("-v verbose error messages");
167 System.out.println("-init initialize the tables");
168 System.out.println("-tpc transactions per client");
169 System.out.println("-clients number of simultaneous clients");
170 System.exit(-1);
171 }
172
173 System.out.println(
174 "*********************************************************");
175 System.out.println(
176 "* JDBCBench v1.1 *");
177 System.out.println(
178 "*********************************************************");
179 System.out.println();
180 System.out.println("Driver: " + DriverName);
181 System.out.println("URL:" + DBUrl);
182 System.out.println();
183 System.out.println("Scale factor value: " + tps);
184 System.out.println("Number of clients: " + n_clients);
185 System.out.println("Number of transactions per client: "
186 + n_txn_per_client);
187 System.out.println();
188
189 try {
190 Class.forName(DriverName);
191
192 JDBCBench Me = new JDBCBench(DBUrl, DBUser, DBPassword,
193 initialize_dataset);
194 } catch (Exception E) {
195 System.out.println(E.getMessage());
196 E.printStackTrace();
197 }
198 }
199
200 public JDBCBench(String url, String user, String password, boolean init) {
201
202 Vector vClient = new Vector();
203 Thread Client = null;
204 Enumeration e = null;
205
206 try {
207 if (init) {
208 System.out.println("Start: "
209 + (new java.util.Date()).toString());
210 System.out.print("Initializing dataset...");
211 createDatabase(url, user, password);
212 System.out.println("done.\n");
213 System.out.println("Complete: "
214 + (new java.util.Date()).toString());
215 }
216
217 System.out.println("* Starting Benchmark Run *");
218
219 MemoryWatcher = new MemoryWatcherThread();
220
221 MemoryWatcher.start();
222
223 transactions = false;
224 prepared_stmt = false;
225 start_time = System.currentTimeMillis();
226
227 for (int i = 0; i < n_clients; i++) {
228 Client = new ClientThread(n_txn_per_client, url, user,
229 password);
230
231 Client.start();
232 vClient.addElement(Client);
233 }
234
235 /*
236 ** Barrier to complete this test session
237 */
238 e = vClient.elements();
239
240 while (e.hasMoreElements()) {
241 Client = (Thread) e.nextElement();
242
243 Client.join();
244 }
245
246 vClient.removeAllElements();
247 reportDone();
248
249 transactions = true;
250 prepared_stmt = false;
251 start_time = System.currentTimeMillis();
252
253 for (int i = 0; i < n_clients; i++) {
254 Client = new ClientThread(n_txn_per_client, url, user,
255 password);
256
257 Client.start();
258 vClient.addElement(Client);
259 }
260
261 /*
262 ** Barrier to complete this test session
263 */
264 e = vClient.elements();
265
266 while (e.hasMoreElements()) {
267 Client = (Thread) e.nextElement();
268
269 Client.join();
270 }
271
272 vClient.removeAllElements();
273 reportDone();
274
275 transactions = false;
276 prepared_stmt = true;
277 start_time = System.currentTimeMillis();
278
279 for (int i = 0; i < n_clients; i++) {
280 Client = new ClientThread(n_txn_per_client, url, user,
281 password);
282
283 Client.start();
284 vClient.addElement(Client);
285 }
286
287 /*
288 ** Barrier to complete this test session
289 */
290 e = vClient.elements();
291
292 while (e.hasMoreElements()) {
293 Client = (Thread) e.nextElement();
294
295 Client.join();
296 }
297
298 vClient.removeAllElements();
299 reportDone();
300
301 transactions = true;
302 prepared_stmt = true;
303 start_time = System.currentTimeMillis();
304
305 for (int i = 0; i < n_clients; i++) {
306 Client = new ClientThread(n_txn_per_client, url, user,
307 password);
308
309 Client.start();
310 vClient.addElement(Client);
311 }
312
313 /*
314 ** Barrier to complete this test session
315 */
316 e = vClient.elements();
317
318 while (e.hasMoreElements()) {
319 Client = (Thread) e.nextElement();
320
321 Client.join();
322 }
323
324 vClient.removeAllElements();
325 reportDone();
326 } catch (Exception E) {
327 System.out.println(E.getMessage());
328 E.printStackTrace();
329 } finally {
330 MemoryWatcher.end();
331
332 try {
333 MemoryWatcher.join();
334
335 if (ShutdownCommand.length() > 0) {
336 Connection C = connect(url, user, password);
337 ;
338 Statement Stmt = C.createStatement();
339
340 Stmt.execute(ShutdownCommand);
341 Stmt.close();
342 connectClose(C);
343 }
344
345 if (TabFile != null) {
346 TabFile.close();
347 }
348 } catch (Exception E1) {}
349
350 System.exit(0);
351 }
352 }
353
354 public void reportDone() {
355
356 long end_time = System.currentTimeMillis();
357 double completion_time = ((double) end_time - (double) start_time)
358 / 1000;
359
360 if (TabFile != null) {
361 TabFile.print(tps + ";" + n_clients + ";" + n_txn_per_client
362 + ";");
363 }
364
365 System.out.println("\n* Benchmark Report *");
366 System.out.print("* Featuring ");
367
368 if (prepared_stmt) {
369 System.out.print("<prepared statements> ");
370
371 if (TabFile != null) {
372 TabFile.print("<prepared statements>;");
373 }
374 } else {
375 System.out.print("<direct queries> ");
376
377 if (TabFile != null) {
378 TabFile.print("<direct queries>;");
379 }
380 }
381
382 if (transactions) {
383 System.out.print("<transactions> ");
384
385 if (TabFile != null) {
386 TabFile.print("<transactions>;");
387 }
388 } else {
389 System.out.print("<auto-commit> ");
390
391 if (TabFile != null) {
392 TabFile.print("<auto-commit>;");
393 }
394 }
395
396 System.out.println("\n--------------------");
397 System.out.println("Time to execute " + transaction_count
398 + " transactions: " + completion_time
399 + " seconds.");
400 System.out.println("Max/Min memory usage: " + MemoryWatcher.max
401 + " / " + MemoryWatcher.min + " kb");
402 System.out.println(failed_transactions + " / " + transaction_count
403 + " failed to complete.");
404
405 double rate = (transaction_count - failed_transactions)
406 / completion_time;
407
408 System.out.println("Transaction rate: " + rate + " txn/sec.");
409
410 if (TabFile != null) {
411 TabFile.print(MemoryWatcher.max + ";" + MemoryWatcher.min + ";"
412 + failed_transactions + ";" + rate + "\n");
413 }
414
415 transaction_count = 0;
416 failed_transactions = 0;
417
418 MemoryWatcher.reset();
419 }
420
421 public synchronized void incrementTransactionCount() {
422 transaction_count++;
423 }
424
425 public synchronized void incrementFailedTransactionCount() {
426 failed_transactions++;
427 }
428
429 void createDatabase(String url, String user,
430 String password) throws Exception {
431
432 Connection Conn = connect(url, user, password);
433 ;
434 String s = Conn.getMetaData().getDatabaseProductName();
435
436 System.out.println("DBMS: " + s);
437
438 transactions = true;
439
440 if (transactions) {
441 try {
442 Conn.setAutoCommit(false);
443 System.out.println("In transaction mode");
444 } catch (SQLException Etrxn) {
445 transactions = false;
446 }
447 }
448
449 try {
450 int accountsnb = 0;
451 Statement Stmt = Conn.createStatement();
452 String Query;
453
454 Query = "SELECT count(*) ";
455 Query += "FROM accounts";
456
457 ResultSet RS = Stmt.executeQuery(Query);
458
459 Stmt.clearWarnings();
460
461 while (RS.next()) {
462 accountsnb = RS.getInt(1);
463 }
464
465 if (transactions) {
466 Conn.commit();
467 }
468
469 Stmt.close();
470
471 if (accountsnb == (naccounts * tps)) {
472 System.out.println("Already initialized");
473 connectClose(Conn);
474
475 return;
476 }
477 } catch (Exception E) {}
478
479 System.out.println("Drop old tables if they exist");
480
481 try {
482 Statement Stmt = Conn.createStatement();
483 String Query;
484
485 Query = "DROP TABLE history";
486
487 Stmt.execute(Query);
488 Stmt.clearWarnings();
489
490 Query = "DROP TABLE accounts";
491
492 Stmt.execute(Query);
493 Stmt.clearWarnings();
494
495 Query = "DROP TABLE tellers";
496
497 Stmt.execute(Query);
498 Stmt.clearWarnings();
499
500 Query = "DROP TABLE branches";
501
502 Stmt.execute(Query);
503 Stmt.clearWarnings();
504
505 if (transactions) {
506 Conn.commit();
507 }
508
509 Stmt.close();
510 } catch (Exception E) {}
511
512 System.out.println("Creates tables");
513
514 try {
515 Statement Stmt = Conn.createStatement();
516 String Query;
517
518 if (tableExtension.length() > 0) {
519 Query = tableExtension + " branches (";
520 } else {
521 Query = "CREATE TABLE branches (";
522 }
523
524 Query += "Bid INTEGER NOT NULL PRIMARY KEY, ";
525 Query += "Bbalance INTEGER,";
526 Query += "filler CHAR(88))"; /* pad to 100 bytes */
527
528 if (createExtension.length() > 0) {
529 Query += createExtension;
530 }
531
532 Stmt.execute(Query);
533 Stmt.clearWarnings();
534
535 if (tableExtension.length() > 0) {
536 Query = tableExtension + " tellers (";
537 } else {
538 Query = "CREATE TABLE tellers (";
539 }
540
541 Query += "Tid INTEGER NOT NULL PRIMARY KEY,";
542 Query += "Bid INTEGER,";
543 Query += "Tbalance INTEGER,";
544 Query += "filler CHAR(84))"; /* pad to 100 bytes */
545
546 if (createExtension.length() > 0) {
547 Query += createExtension;
548 }
549
550 Stmt.execute(Query);
551 Stmt.clearWarnings();
552
553 if (tableExtension.length() > 0) {
554 Query = tableExtension + " accounts (";
555 } else {
556 Query = "CREATE TABLE accounts (";
557 }
558
559 Query += "Aid INTEGER NOT NULL PRIMARY KEY, ";
560 Query += "Bid INTEGER, ";
561 Query += "Abalance INTEGER, ";
562 Query += "filler CHAR(84))"; /* pad to 100 bytes */
563
564 if (createExtension.length() > 0) {
565 Query += createExtension;
566 }
567
568 Stmt.execute(Query);
569 Stmt.clearWarnings();
570
571 if (tableExtension.length() > 0) {
572 Query = tableExtension + " history (";
573 } else {
574 Query = "CREATE TABLE history (";
575 }
576
577 Query += "Tid INTEGER, ";
578 Query += "Bid INTEGER, ";
579 Query += "Aid INTEGER, ";
580 Query += "delta INTEGER, ";
581 Query += "tstime TIMESTAMP, ";
582 Query += "filler CHAR(22))"; /* pad to 50 bytes */
583
584 if (createExtension.length() > 0) {
585 Query += createExtension;
586 }
587
588 Stmt.execute(Query);
589 Stmt.clearWarnings();
590
591 if (transactions) {
592 Conn.commit();
593 }
594
595 Stmt.close();
596 } catch (Exception E) {}
597
598 System.out.println(
599 "Delete elements in table in case Drop didn't work");
600
601 try {
602 Statement Stmt = Conn.createStatement();
603 String Query;
604
605 Query = "DELETE FROM history";
606
607 Stmt.execute(Query);
608 Stmt.clearWarnings();
609
610 Query = "DELETE FROM accounts";
611
612 Stmt.execute(Query);
613 Stmt.clearWarnings();
614
615 Query = "DELETE FROM tellers";
616
617 Stmt.execute(Query);
618 Stmt.clearWarnings();
619
620 Query = "DELETE FROM branches";
621
622 Stmt.execute(Query);
623 Stmt.clearWarnings();
624
625 if (transactions) {
626 Conn.commit();
627 }
628
629 /* prime database using TPC BM B scaling rules.
630 ** Note that for each branch and teller:
631 ** branch_id = teller_id / ntellers
632 ** branch_id = account_id / naccounts
633 */
634 PreparedStatement pstmt = null;
635
636 prepared_stmt = true;
637
638 if (prepared_stmt) {
639 try {
640 Query = "INSERT INTO branches(Bid,Bbalance) VALUES (?,0)";
641 pstmt = Conn.prepareStatement(Query);
642
643 System.out.println("Using prepared statements");
644 } catch (SQLException Epstmt) {
645 pstmt = null;
646 prepared_stmt = false;
647 }
648 }
649
650 System.out.println("Insert data in branches table");
651
652 for (int i = 0; i < nbranches * tps; i++) {
653 if (prepared_stmt) {
654 pstmt.setInt(1, i);
655 pstmt.executeUpdate();
656 pstmt.clearWarnings();
657 } else {
658 Query = "INSERT INTO branches(Bid,Bbalance) VALUES (" + i
659 + ",0)";
660
661 Stmt.executeUpdate(Query);
662 }
663
664 if ((i % 100 == 0) && (transactions)) {
665 Conn.commit();
666 }
667 }
668
669 if (prepared_stmt) {
670 pstmt.close();
671 }
672
673 if (transactions) {
674 Conn.commit();
675 }
676
677 if (prepared_stmt) {
678 Query =
679 "INSERT INTO tellers(Tid,Bid,Tbalance) VALUES (?,?,0)";
680 pstmt = Conn.prepareStatement(Query);
681 }
682
683 System.out.println("Insert data in tellers table");
684
685 for (int i = 0; i < ntellers * tps; i++) {
686 if (prepared_stmt) {
687 pstmt.setInt(1, i);
688 pstmt.setInt(2, i / ntellers);
689 pstmt.executeUpdate();
690 pstmt.clearWarnings();
691 } else {
692 Query = "INSERT INTO tellers(Tid,Bid,Tbalance) VALUES ("
693 + i + "," + i / ntellers + ",0)";
694
695 Stmt.executeUpdate(Query);
696 }
697
698 if ((i % 100 == 0) && (transactions)) {
699 Conn.commit();
700 }
701 }
702
703 if (prepared_stmt) {
704 pstmt.close();
705 }
706
707 if (transactions) {
708 Conn.commit();
709 }
710
711 if (prepared_stmt) {
712 Query =
713 "INSERT INTO accounts(Aid,Bid,Abalance) VALUES (?,?,0)";
714 pstmt = Conn.prepareStatement(Query);
715 }
716
717 System.out.println("Insert data in accounts table");
718
719 for (int i = 0; i < naccounts * tps; i++) {
720 if (prepared_stmt) {
721 pstmt.setInt(1, i);
722 pstmt.setInt(2, i / naccounts);
723 pstmt.executeUpdate();
724 pstmt.clearWarnings();
725 } else {
726 Query = "INSERT INTO accounts(Aid,Bid,Abalance) VALUES ("
727 + i + "," + i / naccounts + ",0)";
728
729 Stmt.executeUpdate(Query);
730 }
731
732 if ((i % 10000 == 0) && (transactions)) {
733 Conn.commit();
734 }
735
736 if ((i > 0) && ((i % 10000) == 0)) {
737 System.out.println("\t" + i + "\t records inserted");
738 }
739 }
740
741 if (prepared_stmt) {
742 pstmt.close();
743 }
744
745 if (transactions) {
746 Conn.commit();
747 }
748
749 System.out.println("\t" + (naccounts * tps)
750 + "\t records inserted");
751 Stmt.close();
752 } catch (Exception E) {
753 System.out.println(E.getMessage());
754 E.printStackTrace();
755 }
756
757 connectClose(Conn);
758 } /* end of CreateDatabase */
759
760 public static int getRandomInt(int lo, int hi) {
761
762 int ret = 0;
763
764 ret = (int) (Math.random() * (hi - lo + 1));
765 ret += lo;
766
767 return ret;
768 }
769
770 public static int getRandomID(int type) {
771
772 int min, max, num;
773
774 max = min = 0;
775 num = naccounts;
776
777 switch (type) {
778
779 case TELLER :
780 min += nbranches;
781 num = ntellers;
782
783 /* FALLTHROUGH */
784 case BRANCH :
785 if (type == BRANCH) {
786 num = nbranches;
787 }
788
789 min += naccounts;
790
791 /* FALLTHROUGH */
792 case ACCOUNT :
793 max = min + num - 1;
794 }
795
796 return (getRandomInt(min, max));
797 }
798
799 public static Connection connect(String DBUrl, String DBUser,
800 String DBPassword) {
801
802 try {
803 Connection conn = DriverManager.getConnection(DBUrl, DBUser,
804 DBPassword);
805
806 return conn;
807 } catch (Exception E) {
808 System.out.println(E.getMessage());
809 E.printStackTrace();
810 }
811
812 return null;
813 }
814
815 public static void connectClose(Connection c) {
816
817 if (c == null) {
818 return;
819 }
820
821 try {
822 c.close();
823 } catch (Exception E) {
824 System.out.println(E.getMessage());
825 E.printStackTrace();
826 }
827 }
828
829 class ClientThread extends Thread {
830
831 int ntrans = 0;
832 Connection Conn;
833 PreparedStatement pstmt1 = null;
834 PreparedStatement pstmt2 = null;
835 PreparedStatement pstmt3 = null;
836 PreparedStatement pstmt4 = null;
837 PreparedStatement pstmt5 = null;
838
839 public ClientThread(int number_of_txns, String url, String user,
840 String password) {
841
842 ntrans = number_of_txns;
843 Conn = connect(url, user, password);
844
845 if (Conn == null) {
846 return;
847 }
848
849 try {
850 if (transactions) {
851 Conn.setAutoCommit(false);
852 }
853
854 if (prepared_stmt) {
855 String Query;
856
857 Query = "UPDATE accounts ";
858 Query += "SET Abalance = Abalance + ? ";
859 Query += "WHERE Aid = ?";
860 pstmt1 = Conn.prepareStatement(Query);
861 Query = "SELECT Abalance ";
862 Query += "FROM accounts ";
863 Query += "WHERE Aid = ?";
864 pstmt2 = Conn.prepareStatement(Query);
865 Query = "UPDATE tellers ";
866 Query += "SET Tbalance = Tbalance + ? ";
867 Query += "WHERE Tid = ?";
868 pstmt3 = Conn.prepareStatement(Query);
869 Query = "UPDATE branches ";
870 Query += "SET Bbalance = Bbalance + ? ";
871 Query += "WHERE Bid = ?";
872 pstmt4 = Conn.prepareStatement(Query);
873 Query = "INSERT INTO history(Tid, Bid, Aid, delta) ";
874 Query += "VALUES (?,?,?,?)";
875 pstmt5 = Conn.prepareStatement(Query);
876 }
877 } catch (Exception E) {
878 System.out.println(E.getMessage());
879 E.printStackTrace();
880 }
881 }
882
883 public void run() {
884
885 while (ntrans-- > 0) {
886 int account = JDBCBench.getRandomID(ACCOUNT);
887 int branch = JDBCBench.getRandomID(BRANCH);
888 int teller = JDBCBench.getRandomID(TELLER);
889 int delta = JDBCBench.getRandomInt(0, 1000);
890
891 doOne(branch, teller, account, delta);
892 incrementTransactionCount();
893 }
894
895 if (prepared_stmt) {
896 try {
897 if (pstmt1 != null) {
898 pstmt1.close();
899 }
900
901 if (pstmt2 != null) {
902 pstmt2.close();
903 }
904
905 if (pstmt3 != null) {
906 pstmt3.close();
907 }
908
909 if (pstmt4 != null) {
910 pstmt4.close();
911 }
912
913 if (pstmt5 != null) {
914 pstmt5.close();
915 }
916 } catch (Exception E) {
917 System.out.println(E.getMessage());
918 E.printStackTrace();
919 }
920 }
921
922 connectClose(Conn);
923
924 Conn = null;
925 }
926
927 /*
928 ** doOne() - Executes a single TPC BM B transaction.
929 */
930 int doOne(int bid, int tid, int aid, int delta) {
931
932 int aBalance = 0;
933
934 if (Conn == null) {
935 incrementFailedTransactionCount();
936
937 return 0;
938 }
939
940 try {
941 if (prepared_stmt) {
942 pstmt1.setInt(1, delta);
943 pstmt1.setInt(2, aid);
944 pstmt1.executeUpdate();
945 pstmt1.clearWarnings();
946 pstmt2.setInt(1, aid);
947
948 ResultSet RS = pstmt2.executeQuery();
949
950 pstmt2.clearWarnings();
951
952 while (RS.next()) {
953 aBalance = RS.getInt(1);
954 }
955
956 pstmt3.setInt(1, delta);
957 pstmt3.setInt(2, tid);
958 pstmt3.executeUpdate();
959 pstmt3.clearWarnings();
960 pstmt4.setInt(1, delta);
961 pstmt4.setInt(2, bid);
962 pstmt4.executeUpdate();
963 pstmt4.clearWarnings();
964 pstmt5.setInt(1, tid);
965 pstmt5.setInt(2, bid);
966 pstmt5.setInt(3, aid);
967 pstmt5.setInt(4, delta);
968 pstmt5.executeUpdate();
969 pstmt5.clearWarnings();
970 } else {
971 Statement Stmt = Conn.createStatement();
972 String Query = "UPDATE accounts ";
973
974 Query += "SET Abalance = Abalance + " + delta + " ";
975 Query += "WHERE Aid = " + aid;
976
977 int res = Stmt.executeUpdate(Query);
978
979 Stmt.clearWarnings();
980
981 Query = "SELECT Abalance ";
982 Query += "FROM accounts ";
983 Query += "WHERE Aid = " + aid;
984
985 ResultSet RS = Stmt.executeQuery(Query);
986
987 Stmt.clearWarnings();
988
989 while (RS.next()) {
990 aBalance = RS.getInt(1);
991 }
992
993 Query = "UPDATE tellers ";
994 Query += "SET Tbalance = Tbalance + " + delta + " ";
995 Query += "WHERE Tid = " + tid;
996
997 Stmt.executeUpdate(Query);
998 Stmt.clearWarnings();
999
1000 Query = "UPDATE branches ";
1001 Query += "SET Bbalance = Bbalance + " + delta + " ";
1002 Query += "WHERE Bid = " + bid;
1003
1004 Stmt.executeUpdate(Query);
1005 Stmt.clearWarnings();
1006
1007 Query = "INSERT INTO history(Tid, Bid, Aid, delta) ";
1008 Query += "VALUES (";
1009 Query += tid + ",";
1010 Query += bid + ",";
1011 Query += aid + ",";
1012 Query += delta + ")";
1013
1014 Stmt.executeUpdate(Query);
1015 Stmt.clearWarnings();
1016 Stmt.close();
1017 }
1018
1019 if (transactions) {
1020 Conn.commit();
1021 }
1022
1023 return aBalance;
1024 } catch (Exception E) {
1025 if (verbose) {
1026 System.out.println("Transaction failed: "
1027 + E.getMessage());
1028 E.printStackTrace();
1029 }
1030
1031 incrementFailedTransactionCount();
1032
1033 if (transactions) {
1034 try {
1035 Conn.rollback();
1036 } catch (SQLException E1) {}
1037 }
1038 }
1039
1040 return 0;
1041 } /* end of DoOne */
1042 } /* end of class ClientThread */
1043
1044 class MemoryWatcherThread extends Thread {
1045
1046 long min = 0;
1047 long max = 0;
1048 boolean keep_running = true;
1049
1050 public MemoryWatcherThread() {
1051
1052 this.reset();
1053
1054 keep_running = true;
1055 }
1056
1057 public void reset() {
1058
1059 System.gc();
1060
1061 long currentFree = Runtime.getRuntime().freeMemory();
1062 long currentAlloc = Runtime.getRuntime().totalMemory();
1063
1064 min = max = (currentAlloc - currentFree);
1065 }
1066
1067 public void end() {
1068 keep_running = false;
1069 }
1070
1071 public void run() {
1072
1073 while (keep_running) {
1074 long currentFree = Runtime.getRuntime().freeMemory();
1075 long currentAlloc = Runtime.getRuntime().totalMemory();
1076 long used = currentAlloc - currentFree;
1077
1078 if (used < min) {
1079 min = used;
1080 }
1081
1082 if (used > max) {
1083 max = used;
1084 }
1085
1086 try {
1087 sleep(100);
1088 } catch (InterruptedException E) {}
1089 }
1090 }
1091 } /* end of class MemoryWatcherThread */
1092}