KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > compare > PerformanceJdbcFailoverTest


1 package org.apache.ojb.compare;
2
3 import java.sql.Connection JavaDoc;
4 import java.sql.PreparedStatement JavaDoc;
5 import java.sql.ResultSet JavaDoc;
6
7 import org.apache.ojb.broker.OJBException;
8 import org.apache.ojb.broker.TestHelper;
9 import org.apache.ojb.broker.accesslayer.ConnectionFactory;
10 import org.apache.ojb.broker.accesslayer.ConnectionFactoryFactory;
11 import org.apache.ojb.broker.metadata.ClassDescriptor;
12 import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
13 import org.apache.ojb.broker.metadata.MetadataManager;
14 import org.apache.ojb.broker.query.Criteria;
15 import org.apache.ojb.broker.query.Query;
16 import org.apache.ojb.broker.query.QueryByCriteria;
17 import org.apache.ojb.broker.util.logging.Logger;
18 import org.apache.ojb.broker.util.logging.LoggerFactory;
19 import org.apache.ojb.junit.PBTestCase;
20
21 /**
22  * This TestCase contains the OJB performance benchmarks for the
23  * JDBC API. The original testcases have been enhanced with
24  * code dealing with db failover situations.
25  * @author Thomas Mahler
26  */

27 public class PerformanceJdbcFailoverTest extends PBTestCase
28 {
29     private Logger logger = LoggerFactory.getLogger("failover");
30
31     /**
32      * the number of PerformanceArticle objects to work with.
33      */

34     static int articleCount = 10000;
35
36     /**
37      * the number of iterations to perform.
38      */

39     static int iterations = 2;
40
41     /**
42      * the maximum number of retries if db fails.
43      */

44     static int maxRetries = 5;
45
46     /**
47      * the maximum time to wait on db availability.
48      */

49     static int maxWait = 30;
50
51
52     /**
53      * the offset value for PerformanceArticle primary keys
54      */

55     int offsetId = 10000;
56     private PerformanceArticle[] arr;
57     private int actualRetries = 0;
58
59     /**
60      * BrokerTests constructor comment.
61      * @param name java.lang.String
62      */

63     public PerformanceJdbcFailoverTest(String JavaDoc name)
64
65     {
66         super(name);
67     }
68
69     /**
70      * launches the TestCase.
71      * The number of Objects to work with and the number of iterations
72      * to be performed can be adjusted by setting them as commandline parameters.
73      * @param args the String[] holding the commandline parameters.
74      */

75     public static void main(String JavaDoc[] args)
76     {
77         if (args.length > 0)
78         {
79             articleCount = Integer.parseInt(args[0]);
80         }
81         if (args.length > 1)
82         {
83             iterations = Integer.parseInt(args[1]);
84         }
85         if (args.length > 2)
86         {
87             maxRetries = Integer.parseInt(args[2]);
88         }
89         if (args.length > 3)
90         {
91             maxWait = Integer.parseInt(args[3]);
92         }
93
94
95         String JavaDoc[] arr = {PerformanceJdbcFailoverTest.class.getName()};
96         junit.textui.TestRunner.main(arr);
97     }
98
99     /**
100      * setting up the test fixture.
101      */

102     public void setUp() throws Exception JavaDoc
103     {
104         super.setUp();
105
106         clearTable();
107         arr = new PerformanceArticle[articleCount];
108         for (int i = 0; i < articleCount; i++)
109         {
110             PerformanceArticle a = createArticle(offsetId + i);
111             arr[i] = a;
112         }
113     }
114
115     /**
116      * tearing down the test fixture.
117      */

118     public void tearDown() throws Exception JavaDoc
119     {
120         super.tearDown();
121     }
122
123     /**
124      * factory method that createa an PerformanceArticle with a given id.
125      * @return the created PerformanceArticle object
126      * @param id the primary key value for the new object
127      */

128     private PerformanceArticle createArticle(int id)
129     {
130         PerformanceArticle a = new PerformanceArticle();
131         a.setArticleId(new Integer JavaDoc(id));
132         a.setArticleName("New Performance Article " + id);
133         a.setMinimumStock(100);
134         a.setOrderedUnits(17);
135         a.setPrice(100.0);
136         a.setProductGroupId(1);
137         a.setStock(234);
138         a.setSupplierId(4);
139         a.setUnit("bottle");
140         return a;
141     }
142
143     /**
144      * obtain a JDBC Connection. OJB API is used to make this code portable for
145      * other target dabases and different lookup methods.
146      * @return the Connection to be used
147      */

148     private Connection JavaDoc getConnection() throws Exception JavaDoc
149     {
150         Connection JavaDoc conn = null;
151         long startToWait = System.currentTimeMillis();
152         System.out.print("[");
153         System.out.flush();
154         while (true)
155         {
156             try
157             {
158                 // Use OJB API to obtain JDBC Connection. All settings are read from
159
// the repository.xml file.
160
JdbcConnectionDescriptor jcd =
161                         MetadataManager.getInstance().connectionRepository().getDescriptor(
162                                 TestHelper.DEF_KEY);
163                 ConnectionFactory cf =
164                         ConnectionFactoryFactory.getInstance().createConnectionFactory();
165                 conn = cf.lookupConnection(jcd);
166                 System.out.println("] Waited for connection " + (System.currentTimeMillis() - startToWait) + "msecs");
167                 break;
168             }
169             catch (Throwable JavaDoc t)
170             {
171                 long now = System.currentTimeMillis();
172                 if ((now - startToWait) > (1000* maxWait))
173                 {
174                     System.out.print("Timeout exceeded in getConnection(), DB not available!");
175                     throw new OJBException(t);
176                 }
177                 else
178                 {
179                     if ((now % 1000) == 0)
180                     {
181                         System.out.print("#");
182                         System.out.flush();
183                     }
184                     
185                 }
186             }
187         }
188         return conn;
189     }
190
191     /**
192      * deletes all PerformanceArticle created by <code>insertNewArticles</code>.
193      */

194     protected void deleteArticles() throws Exception JavaDoc
195     {
196         Connection JavaDoc conn = getConnection();
197
198         // Use the OJB SqlGenerator to generate SQL Statements. All details about
199
// Table and column names are read from the repository.xml file.
200
ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
201         String JavaDoc sql = broker.serviceSqlGenerator().getPreparedDeleteStatement(cld).getStatement();
202
203         logger.debug("delete stmt: " + sql);
204
205         long start = System.currentTimeMillis();
206         try
207         {
208             conn.setAutoCommit(false);
209             PreparedStatement JavaDoc stmt = conn.prepareStatement(sql);
210             for (int i = 0; i < articleCount; i++)
211             {
212                 PerformanceArticle a = arr[i];
213                 stmt.setInt(1, a.articleId.intValue());
214                 stmt.execute();
215             }
216             conn.commit();
217         }
218         catch (Throwable JavaDoc t)
219         {
220             actualRetries++;
221             if (actualRetries <= maxRetries)
222             {
223                 logger.error("error during db operations:", t);
224                 try
225                 {
226                     conn.close();
227                 }
228                 catch (Throwable JavaDoc ignored)
229                 {
230                 }
231                 deleteArticles();
232             }
233             else
234             {
235                 logger.error("retry count exceeded!");
236                 fail(t.getMessage());
237             }
238         }
239         finally
240         {
241             try
242             {
243                 conn.close();
244             }
245             catch (Throwable JavaDoc ignored)
246             {
247             }
248         }
249         long stop = System.currentTimeMillis();
250         logger.info("deleting " + articleCount + " Objects: " + (stop - start) + " msec");
251     }
252
253     /**
254      * create new PerformanceArticle objects and insert them into the RDBMS.
255      * The number of objects to create is defined by <code>articleCount</code>.
256      */

257     protected void insertNewArticles() throws Exception JavaDoc
258     {
259         Connection JavaDoc conn = getConnection();
260
261         // Use the OJB SqlGenerator to generate SQL Statements. All details about
262
// Table and column names are read from the repository.xml file.
263
ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
264         String JavaDoc sql = broker.serviceSqlGenerator().getPreparedInsertStatement(cld).getStatement();
265
266         logger.debug("insert stmt: " + sql);
267
268         long start = System.currentTimeMillis();
269         try
270         {
271             conn.setAutoCommit(false);
272             PreparedStatement JavaDoc stmt = conn.prepareStatement(sql);
273
274             for (int i = 0; i < articleCount; i++)
275             {
276                 PerformanceArticle a = arr[i];
277
278                 stmt.setInt(1, a.articleId.intValue());
279                 stmt.setString(2, a.articleName);
280                 stmt.setInt(3, a.supplierId);
281                 stmt.setInt(4, a.productGroupId);
282                 stmt.setString(5, a.unit);
283                 stmt.setDouble(6, a.price);
284                 stmt.setInt(7, a.stock);
285                 stmt.setInt(8, a.orderedUnits);
286                 stmt.setInt(9, a.minimumStock);
287
288                 stmt.execute();
289             }
290             conn.commit();
291         }
292         catch (Throwable JavaDoc t)
293         {
294             actualRetries++;
295             if (actualRetries <= maxRetries)
296             {
297                 logger.error("error during db operations:", t);
298                 try
299                 {
300                     conn.close();
301                 }
302                 catch (Throwable JavaDoc ignored)
303                 {
304                 }
305                 insertNewArticles();
306             }
307             else
308             {
309                 logger.error("retry count exceeded!");
310                 fail(t.getMessage());
311             }
312         }
313         finally
314         {
315             try
316             {
317                 conn.close();
318             }
319             catch (Throwable JavaDoc ignored)
320             {
321             }
322         }
323         long stop = System.currentTimeMillis();
324         logger.info("inserting " + articleCount + " Objects: " + (stop - start) + " msec");
325
326     }
327
328     protected void clearTable() throws Exception JavaDoc
329     {
330         Connection JavaDoc conn = getConnection();
331         try
332         {
333             ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
334             String JavaDoc table = cld.getFullTableName();
335             String JavaDoc sql = "DELETE FROM " + table;
336             PreparedStatement JavaDoc stmt = conn.prepareStatement(sql);
337             stmt.execute();
338             conn.close();
339         }
340         catch (Throwable JavaDoc t)
341         {
342             actualRetries++;
343             if (actualRetries <= maxRetries)
344             {
345                 logger.error("error during db operations:", t);
346                 try
347                 {
348                     conn.close();
349                 }
350                 catch (Throwable JavaDoc ignored)
351                 {
352                 }
353                 clearTable();
354             }
355             else
356             {
357                 logger.error("retry count exceeded!");
358                 fail(t.getMessage());
359             }
360         }
361         finally
362         {
363             try
364             {
365                 conn.close();
366             }
367             catch (Throwable JavaDoc ignored)
368             {
369             }
370         }
371     }
372
373     /**
374      * read in all the PerformanceArticles from the RDBMS that have
375      * been inserted by <code>insertNewArticles()</code>.
376      * The lookup is done one by one, that is: a primary key based lookup is used.
377      */

378     protected void readArticles() throws Exception JavaDoc
379     {
380         Connection JavaDoc conn = getConnection();
381
382         // Use the OJB SqlGenerator to generate SQL Statements. All details about
383
// Table and column names are read from the repository.xml file.
384
ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
385         String JavaDoc sql = broker.serviceSqlGenerator().getPreparedSelectByPkStatement(cld).getStatement();
386         logger.debug("select stmt: " + sql);
387         long start = System.currentTimeMillis();
388
389         String JavaDoc colId = cld.getFieldDescriptorByName("articleId").getColumnName();
390         String JavaDoc colName = cld.getFieldDescriptorByName("articleName").getColumnName();
391         String JavaDoc colSupplier = cld.getFieldDescriptorByName("supplierId").getColumnName();
392         String JavaDoc colGroup = cld.getFieldDescriptorByName("productGroupId").getColumnName();
393         String JavaDoc colUnit = cld.getFieldDescriptorByName("unit").getColumnName();
394         String JavaDoc colPrice = cld.getFieldDescriptorByName("price").getColumnName();
395         String JavaDoc colStock = cld.getFieldDescriptorByName("stock").getColumnName();
396         String JavaDoc colOrdered = cld.getFieldDescriptorByName("orderedUnits").getColumnName();
397         String JavaDoc colMin = cld.getFieldDescriptorByName("minimumStock").getColumnName();
398
399         try
400         {
401             conn.setAutoCommit(false);
402             PreparedStatement JavaDoc stmt = conn.prepareStatement(sql);
403             for (int i = 0; i < articleCount; i++)
404             {
405                 stmt.setInt(1, offsetId + i);
406                 ResultSet JavaDoc rs = stmt.executeQuery();
407                 rs.next();
408
409                 PerformanceArticle a = new PerformanceArticle();
410                 a.articleId = new Integer JavaDoc(rs.getInt(colId));
411                 a.articleName = rs.getString(colName);
412                 a.supplierId = rs.getInt(colSupplier);
413                 a.productGroupId = rs.getInt(colGroup);
414                 a.unit = rs.getString(colUnit);
415                 a.price = rs.getFloat(colPrice);
416                 a.stock = rs.getInt(colStock);
417                 a.orderedUnits = rs.getInt(colOrdered);
418                 a.minimumStock = rs.getInt(colMin);
419             }
420         }
421         catch (Throwable JavaDoc t)
422         {
423             actualRetries++;
424             if (actualRetries <= maxRetries)
425             {
426                 logger.error("error during db operations:", t);
427                 try
428                 {
429                     conn.close();
430                 }
431                 catch (Throwable JavaDoc ignored)
432                 {
433                 }
434                 readArticles();
435             }
436             else
437             {
438                 logger.error("retry count exceeded!");
439                 fail(t.getMessage());
440             }
441         }
442         finally
443         {
444             try
445             {
446                 conn.close();
447             }
448             catch (Throwable JavaDoc ignored)
449             {
450             }
451         }
452
453
454         long stop = System.currentTimeMillis();
455         logger.info("querying " + articleCount + " Objects: " + (stop - start) + " msec");
456
457     }
458
459     /**
460      * read in all the PerformanceArticles from the RDBMS that have
461      * been inserted by <code>insertNewArticles()</code>.
462      * The lookup is done with a cursor fetch,
463      * that is: a between Statement is used to select all inserted PerformanceArticles
464      * and Objects are read in by fetching from the cursor (JDBC ResultSet).
465      */

466     protected void readArticlesByCursor() throws Exception JavaDoc
467     {
468         Connection JavaDoc conn = getConnection();
469
470         Criteria c = new Criteria();
471         c.addBetween("articleId", new Integer JavaDoc(offsetId), new Integer JavaDoc(offsetId + articleCount));
472         Query query = new QueryByCriteria(PerformanceArticle.class, c);
473
474         // Use the OJB SqlGenerator to generate SQL Statements. All details about
475
// Table and column names are read from the repository.xml file.
476
ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
477         String JavaDoc sql = broker.serviceSqlGenerator().getPreparedSelectStatement(query, cld).getStatement();
478
479         logger.debug("select stmt: " + sql);
480         long start = System.currentTimeMillis();
481
482         String JavaDoc colId = cld.getFieldDescriptorByName("articleId").getColumnName();
483         String JavaDoc colName = cld.getFieldDescriptorByName("articleName").getColumnName();
484         String JavaDoc colSupplier = cld.getFieldDescriptorByName("supplierId").getColumnName();
485         String JavaDoc colGroup = cld.getFieldDescriptorByName("productGroupId").getColumnName();
486         String JavaDoc colUnit = cld.getFieldDescriptorByName("unit").getColumnName();
487         String JavaDoc colPrice = cld.getFieldDescriptorByName("price").getColumnName();
488         String JavaDoc colStock = cld.getFieldDescriptorByName("stock").getColumnName();
489         String JavaDoc colOrdered = cld.getFieldDescriptorByName("orderedUnits").getColumnName();
490         String JavaDoc colMin = cld.getFieldDescriptorByName("minimumStock").getColumnName();
491
492         int fetchCount = 0;
493         try
494         {
495             conn.setAutoCommit(false);
496             PreparedStatement JavaDoc stmt = conn.prepareStatement(sql);
497             stmt.setInt(1, offsetId);
498             stmt.setInt(2, offsetId + articleCount);
499             ResultSet JavaDoc rs = stmt.executeQuery();
500             while (rs.next())
501             {
502                 fetchCount++;
503
504                 PerformanceArticle a = new PerformanceArticle();
505                 a.articleId = new Integer JavaDoc(rs.getInt(colId));
506                 a.articleName = rs.getString(colName);
507                 a.supplierId = rs.getInt(colSupplier);
508                 a.productGroupId = rs.getInt(colGroup);
509                 a.unit = rs.getString(colUnit);
510                 a.price = rs.getFloat(colPrice);
511                 a.stock = rs.getInt(colStock);
512                 a.orderedUnits = rs.getInt(colOrdered);
513                 a.minimumStock = rs.getInt(colMin);
514             }
515         }
516         catch (Throwable JavaDoc t)
517         {
518             actualRetries++;
519             if (actualRetries <= maxRetries)
520             {
521                 logger.error("error during db operations:", t);
522                 try
523                 {
524                     conn.close();
525                 }
526                 catch (Throwable JavaDoc ignored)
527                 {
528                 }
529                 readArticlesByCursor();
530             }
531             else
532             {
533                 logger.error("retry count exceeded!");
534                 fail(t.getMessage());
535             }
536         }
537         finally
538         {
539             try
540             {
541                 conn.close();
542             }
543             catch (Throwable JavaDoc ignored)
544             {
545             }
546         }
547
548
549         long stop = System.currentTimeMillis();
550         logger.info("fetching " + fetchCount + " Objects: " + (stop - start) + " msec");
551
552     }
553
554     /**
555      * updates all PerformanceArticles inserted by <code>insertNewArticles()</code>.
556      * All objects are modified and changes are written to the RDBMS with an UPDATE.
557      */

558     protected void updateExistingArticles() throws Exception JavaDoc
559     {
560         Connection JavaDoc conn = getConnection();
561
562         // Use the OJB SqlGenerator to generate SQL Statements. All details about
563
// Table and column names are read from the repository.xml file.
564
ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
565         String JavaDoc sql = broker.serviceSqlGenerator().getPreparedUpdateStatement(cld).getStatement();
566         logger.debug("update stmt: " + sql);
567
568         // update all objects
569
for (int i = 0; i < articleCount; i++)
570         {
571             arr[i].setPrice(arr[i].getPrice() * 1.95583);
572         }
573
574         long start = System.currentTimeMillis();
575         try
576         {
577             conn.setAutoCommit(false);
578             PreparedStatement JavaDoc stmt = conn.prepareStatement(sql);
579             for (int i = 0; i < articleCount; i++)
580             {
581                 PerformanceArticle a = arr[i];
582                 stmt.setString(1, a.articleName);
583                 stmt.setInt(2, a.supplierId);
584                 stmt.setInt(3, a.productGroupId);
585                 stmt.setString(4, a.unit);
586                 stmt.setDouble(5, a.price);
587                 stmt.setInt(6, a.stock);
588                 stmt.setInt(7, a.orderedUnits);
589                 stmt.setInt(8, a.minimumStock);
590                 stmt.setInt(9, a.articleId.intValue());
591                 stmt.execute();
592             }
593             conn.commit();
594         }
595         catch (Throwable JavaDoc t)
596         {
597             actualRetries++;
598             if (actualRetries <= maxRetries)
599             {
600                 logger.error("error during db operations:", t);
601                 try
602                 {
603                     conn.close();
604                 }
605                 catch (Throwable JavaDoc ignored)
606                 {
607                 }
608                 updateExistingArticles();
609             }
610             else
611             {
612                 logger.error("retry count exceeded!");
613                 fail(t.getMessage());
614             }
615         }
616         finally
617         {
618             try
619             {
620                 conn.close();
621             }
622             catch (Throwable JavaDoc ignored)
623             {
624             }
625         }
626         long stop = System.currentTimeMillis();
627         logger.info("updating " + articleCount + " Objects: " + (stop - start) + " msec");
628
629     }
630
631     /**
632      * this method is the driver for the complete Benchmark.
633      * It performs the following steps:
634      *
635      * 1.) n objects are created and inserted to the RDBMS.
636      * 2.) the created objects are modified. Modifications are written to the RDBMS with updates.
637      * 3.) All objects created in 1.) are read in by primary key based SELECT statements.
638      * 4.) Step 3.) is repeated to test caching facilities.
639      * 5.) All objects created in 1.) are read by iterating over a ResultSet.
640      * 6.) All objects created in 1.) are deleted with n separate DELETE Statements.
641      */

642     public void testBenchmark()
643     {
644         try
645         {
646             logger.info("Test for native JDBC");
647             for (int i = 0; i < iterations; i++)
648             {
649                 logger.info("");
650
651                 // store all Article objects
652
insertNewArticles();
653
654                 // update all objects
655
updateExistingArticles();
656
657                 // querying
658
readArticles();
659
660                 readArticles();
661
662                 // fetching objects
663
readArticlesByCursor();
664
665                 // delete all objects
666
deleteArticles();
667             }
668         }
669         catch (Throwable JavaDoc t)
670         {
671             logger.error(t);
672             fail(t.getMessage());
673         }
674     }
675
676 }
677
Popular Tags