Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

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}