36
36
import testsuite .clusterj .model .Order ;
37
37
import testsuite .clusterj .model .OrderLine ;
38
38
39
- @ org .junit .Ignore ("disable test until diagnosis of failure" )
39
+ // @org.junit.Ignore("disable test until diagnosis of failure")
40
40
public class ReconnectTest extends AbstractClusterJModelTest {
41
41
42
42
@ Override
43
43
protected boolean getDebug () {
44
44
return false ;
45
45
}
46
46
47
- private long sleepBeforeReconnectMillis = 20 ;
47
+ private long sleepBeforeReconnectMillis = 1 ;
48
48
private int numberOfThreads = 30 ;
49
49
private int numberOfNewCustomersPerThread = 5 ;
50
50
private int numberOfNewOrdersPerNewCustomer = 5 ;
@@ -136,19 +136,21 @@ public void test() {
136
136
// create uncaught exception handler
137
137
MyUncaughtExceptionHandler uncaughtExceptionHandler = new MyUncaughtExceptionHandler ();
138
138
Thread .setDefaultUncaughtExceptionHandler (uncaughtExceptionHandler );
139
- // create all threads
139
+ // create the thread that misbehaves
140
+ Thread misbehaving = new Thread (threadGroup , new Misbehaving ());
141
+ threads .add (misbehaving );
142
+ // create all normal threads
140
143
for (int i = 0 ; i < numberOfThreads ; ++i ) {
141
144
Thread thread = new Thread (threadGroup , new StuffToDo ());
142
145
threads .add (thread );
146
+ }
147
+ // start all threads
148
+ for (Thread thread : threads ) {
143
149
thread .start ();
144
150
}
145
- // create the thread that misbehaves
146
- Thread misbehaving = new Thread (threadGroup , new Misbehaving ());
147
- threads .add (misbehaving );
148
- misbehaving .start ();
149
151
// tell the SessionFactory to reconnect
150
152
sleep (sleepBeforeReconnectMillis );
151
- sessionFactory .reconnect ();
153
+ sessionFactory .reconnect (5 );
152
154
// wait until all threads have finished
153
155
for (Thread t : threads ) {
154
156
try {
@@ -209,12 +211,13 @@ public void test() {
209
211
actualTotal += orderLine .getTotalValue ();
210
212
}
211
213
errorIfNotEqual ("For order " + orderId + ", order value does not equal sum of order line values."
212
- + " orderLines: " + messages .toString (),
214
+ + " orderLines: \n " + messages .toString (),
213
215
expectedTotal , actualTotal );
214
216
}
215
217
done = true ;
216
218
} catch (Throwable t ) {
217
219
if (getDebug ()) { System .out .println ("summarize for the record caught " + t .getMessage ()); }
220
+ sleep (1000 );
218
221
}
219
222
}
220
223
failOnError ();
@@ -276,27 +279,39 @@ public void run() {
276
279
session .close ();
277
280
done = true ;
278
281
} catch (ClusterJUserException cjue ) {
282
+ if (getDebug ()) { System .out .println ("StuffToDo: query orderId caught " + cjue .getMessage ()); }
279
283
if (cjue .getMessage ().contains ("SessionFactory is not open" )) {
280
- sleep (1000 );
284
+ sleep (300 );
281
285
}
282
286
}
283
287
}
284
288
int i = 0 ;
285
289
while (i < numberOfNewCustomersPerThread ) {
286
290
// create a new customer
287
291
try (Session localSession = sessionFactory .getSession ()) {
292
+ Customer customer = null ;
293
+ List <Customer > newCustomers = new ArrayList <Customer >(numberOfNewCustomersPerThread );
294
+ Order order = null ;
295
+ List <Order > newOrders = new ArrayList <Order >(
296
+ numberOfNewCustomersPerThread * numberOfNewOrdersPerNewCustomer );
288
297
localSession .currentTransaction ().begin ();
289
- createCustomer (localSession , String .valueOf (Thread .currentThread ().getId ()));
290
- for (int j = 0 ; j < numberOfNewOrdersPerNewCustomer ; ++j ) {
291
- // create a new order
292
- createOrder (localSession , myRandom );
293
- }
294
- ++i ;
298
+ customer = createCustomer (localSession , String .valueOf (Thread .currentThread ().getId ()));
299
+ newCustomers .add (customer );
300
+ int customerId = customer .getId ();
301
+ for (int j = 0 ; j < numberOfNewOrdersPerNewCustomer ; ++j ) {
302
+ // create a new order for the customer
303
+ newOrders .add (createOrder (localSession , customerId , myRandom ));
304
+ }
305
+ ++i ;
295
306
localSession .currentTransaction ().commit ();
307
+ // add new customers and orders only if successful
308
+ addCustomers (newCustomers );
309
+ addOrders (newOrders );
296
310
} catch (ClusterJUserException cjue ) {
311
+ if (getDebug ()) { System .out .println ("StuffToDo: create customer caught " + cjue .getMessage ()); }
297
312
if (cjue .getMessage ().contains ("SessionFactory is not open" )) {
298
313
incrementRetryCount ();
299
- sleep (1000 );
314
+ sleep (300 );
300
315
}
301
316
}
302
317
}
@@ -306,13 +321,16 @@ public void run() {
306
321
try (Session localSession = sessionFactory .getSession ()) {
307
322
// update an order
308
323
localSession .currentTransaction ().begin ();
309
- updateOrder (localSession , myRandom , queryOrderType );
324
+ Order order = updateOrder (localSession , myRandom , queryOrderType );
310
325
localSession .currentTransaction ().commit ();
326
+ // put the updated order back
327
+ addOrder (order );
311
328
++i ;
312
329
} catch (ClusterJUserException cjue ) {
330
+ if (getDebug ()) { System .out .println ("StuffToDo: update orders caught " + cjue .getMessage ()); }
313
331
if (cjue .getMessage ().contains ("SessionFactory is not open" )) {
314
332
incrementRetryCount ();
315
- sleep (1000 );
333
+ sleep (300 );
316
334
}
317
335
}
318
336
}
@@ -327,8 +345,9 @@ public void run() {
327
345
done = true ;
328
346
} catch (ClusterJUserException cjue ) {
329
347
if (cjue .getMessage ().contains ("SessionFactory is not open" )) {
348
+ if (getDebug ()) { System .out .println ("StuffToDo: delete order caught " + cjue .getMessage ()); }
330
349
incrementRetryCount ();
331
- sleep (1000 );
350
+ sleep (300 );
332
351
} else {
333
352
System .out .println ("deleteOrder threw " + cjue .getMessage ());
334
353
}
@@ -340,44 +359,45 @@ public void run() {
340
359
/** Create a new customer.
341
360
* @param session the session
342
361
* @param threadId the thread id of the creating thread
362
+ * @return the new customer
343
363
*/
344
- private void createCustomer (Session session , String threadId ) {
364
+ private Customer createCustomer (Session session , String threadId ) {
345
365
Customer customer = session .newInstance (Customer .class );
346
366
int id = getNextCustomerId ();
347
367
customer .setId (id );
348
368
customer .setName ("Customer number " + id + " thread " + threadId );
349
369
customer .setMagic (id * 10000 );
350
- session .makePersistent (customer ); // autocommit for this
351
- addCustomer ( customer ) ;
370
+ session .makePersistent (customer );
371
+ return customer ;
352
372
}
353
373
354
- /** Create a new order. Add a new order with a random number of order lines
374
+ /** Create a new order for a specific customer with a random number of order lines
355
375
* and a random unit price and quantity.
356
376
* @param session the session
357
- * @param random a random number generator
377
+ * @param customer the customer
378
+ * @param random the random number generator
379
+ * @return the new order
358
380
*/
359
- public void createOrder (Session session , Random random ) {
381
+ public Order createOrder (Session session , int customerId , Random random ) {
360
382
// get an order number
361
383
int orderid = getNextOrderId ();
362
384
Order order = session .newInstance (Order .class );
363
385
order .setId (orderid );
364
- // get a random customer number
365
- int customerId = random .nextInt (nextCustomerId );
366
386
order .setCustomerId (customerId );
367
387
order .setDescription ("Order " + orderid + " for Customer " + customerId );
368
388
Double orderValue = 0.0d ;
369
389
// now create some order lines
370
- int numberOfOrderLines = random .nextInt (maximumOrderLinesPerOrder );
390
+ int numberOfOrderLines = random .nextInt (maximumOrderLinesPerOrder ) + 1 ;
371
391
if (getDebug ()) System .out .println ("Create Order " + orderid
372
392
+ " with numberOfOrderLines: " + numberOfOrderLines );
373
393
for (int i = 0 ; i < numberOfOrderLines ; ++i ) {
374
394
int orderLineNumber = getNextOrderLineId ();
375
395
OrderLine orderLine = session .newInstance (OrderLine .class );
376
396
orderLine .setId (orderLineNumber );
377
397
orderLine .setOrderId (orderid );
378
- long quantity = random .nextInt (maximumQuantityPerOrderLine );
398
+ long quantity = random .nextInt (maximumQuantityPerOrderLine ) + 1 ;
379
399
orderLine .setQuantity (quantity );
380
- float unitPrice = ((float )random .nextInt (maximumUnitPrice )) / 4 ;
400
+ float unitPrice = (1.0f + (float )random .nextInt (maximumUnitPrice )) / 4 ;
381
401
orderLine .setUnitPrice (unitPrice );
382
402
double orderLineValue = unitPrice * quantity ;
383
403
orderValue += orderLineValue ;
@@ -390,39 +410,41 @@ public void createOrder(Session session, Random random) {
390
410
}
391
411
order .setValue (orderValue );
392
412
session .persist (order );
393
- addOrder ( order ) ;
413
+ return order ;
394
414
}
395
415
396
416
/** Update an order; change one or more order lines
397
417
* @param session the session
398
418
* @param random a random number generator
399
419
* @param query
400
420
*/
401
- public void updateOrder (Session session , Random random , QueryDomainType <OrderLine > queryOrderType ) {
421
+ public Order updateOrder (Session session , Random random , QueryDomainType <OrderLine > queryOrderType ) {
402
422
Order order = null ;
403
423
// pick an order to update; prevent anyone else from updating the same order
404
424
order = removeOrderFromOrdersCollection (random );
405
- if (order == null ) { return ; }
425
+ if (order == null ) { return null ; }
406
426
int orderId = order .getId ();
407
427
// replace order with its persistent representation
408
428
order = session .find (Order .class , orderId );
409
- if (order == null ) { return ; }
429
+ if (order == null ) { return null ; }
410
430
List <OrderLine > orderLines = getOrderLines (session , queryOrderType , orderId );
411
431
int numberOfOrderLines = orderLines .size ();
412
432
OrderLine orderLine = null ;
413
433
double orderValue = order .getValue ();
434
+ if (getDebug ()) { System .out .println ("updateOrder previous orderValue: " + orderValue ); }
414
435
if (numberOfOrderLines > 0 ) {
415
436
int index = random .nextInt (numberOfOrderLines );
416
437
orderLine = orderLines .get (index );
417
438
orderValue -= orderLine .getTotalValue ();
418
439
updateOrderLine (orderLine , random );
419
440
orderValue += orderLine .getTotalValue ();
420
441
}
442
+ if (getDebug ()) { System .out .println ("updateOrder updated orderValue: " + orderValue ); }
421
443
order .setValue (orderValue );
422
444
session .updatePersistent (orderLine );
423
445
session .updatePersistent (order );
424
- // put order back now that we're done updating it
425
- addOrder ( order ) ;
446
+ // return order so it can be put back after committing the transaction
447
+ return order ;
426
448
}
427
449
428
450
/** Update an order line by randomly changing unit price and quantity.
@@ -492,17 +514,26 @@ private void removeOrderLinesFromOrderLinesCollection(Collection<OrderLine> orde
492
514
}
493
515
}
494
516
495
- /** Add a new customer to the list of customers
496
- * @param customer
517
+ /** Add a new customer to the list of customers (multithread safe)
518
+ * @param customer the customer to add
497
519
*/
498
520
private void addCustomer (Customer customer ) {
499
521
synchronized (customers ) {
500
522
customers .add (customer );
501
523
}
502
524
}
503
525
526
+ /** Add new customers to the list of customers (multithread safe)
527
+ * @param newCustomers the customers to add
528
+ */
529
+ private void addCustomers (Collection <Customer > newCustomers ) {
530
+ synchronized (customers ) {
531
+ customers .addAll (newCustomers );
532
+ }
533
+ }
534
+
504
535
/** Get the next customer number (multithread safe)
505
- * @return
536
+ * @return the next customer id
506
537
*/
507
538
private int getNextCustomerId () {
508
539
synchronized (customers ) {
@@ -512,7 +543,7 @@ private int getNextCustomerId() {
512
543
}
513
544
514
545
/** Get the next order number (multithread safe)
515
- * @return
546
+ * @return the next order number
516
547
*/
517
548
private int getNextOrderId () {
518
549
synchronized (orders ) {
@@ -531,7 +562,7 @@ private int getNextOrderLineId() {
531
562
}
532
563
}
533
564
534
- /** Add an order to the list of orders.
565
+ /** Add an order to the list of orders. (multithread safe)
535
566
* @param order the order
536
567
*/
537
568
private void addOrder (Order order ) {
@@ -540,7 +571,16 @@ private void addOrder(Order order) {
540
571
}
541
572
}
542
573
543
- /** Add an order line to the list of order lines.
574
+ /** Add a collection of orders to the list of orders. (multithread safe)
575
+ * @param newOrders the collection of orders
576
+ */
577
+ private void addOrders (Collection <Order > newOrders ) {
578
+ synchronized (orders ) {
579
+ orders .addAll (newOrders );
580
+ }
581
+ }
582
+
583
+ /** Add an order line to the list of order lines. (multithread safe)
544
584
* @param orderLine the order line
545
585
*/
546
586
private void addOrderLine (OrderLine orderLine ) {
0 commit comments