@@ -596,13 +596,48 @@ public void runInReadTx(Runnable runnable) {
596
596
}
597
597
}
598
598
599
+ @ Experimental
600
+ public <T > T callInReadTxWithRetry (Callable <T > callable , int attempts , int initialBackOffInMs , boolean logAndHeal ) {
601
+ if (attempts == 1 ) {
602
+ return callInReadTx (callable );
603
+ }
604
+ long backoffInMs = initialBackOffInMs ;
605
+ DbException lastException = null ;
606
+ for (int attempt = 1 ; attempt <= attempts ; attempt ++) {
607
+ try {
608
+ return callInReadTx (callable );
609
+ } catch (DbException e ) {
610
+ lastException = e ;
611
+ if (logAndHeal ) {
612
+ System .err .println (attempt + ". of " + attempts + " attempts of calling a read TX failed:" );
613
+ e .printStackTrace ();
614
+ System .err .println (diagnose ());
615
+ System .err .flush ();
616
+
617
+ System .gc ();
618
+ System .runFinalization ();
619
+ cleanStaleReadTransactions ();
620
+ }
621
+ try {
622
+ Thread .sleep (backoffInMs );
623
+ } catch (InterruptedException ie ) {
624
+ ie .printStackTrace ();
625
+ throw lastException ;
626
+ }
627
+ backoffInMs *= 2 ;
628
+ }
629
+ }
630
+ throw lastException ;
631
+ }
632
+
599
633
/**
600
634
* Calls the given callable inside a read(-only) transaction. Multiple read transactions can occur at the same time.
601
635
* This allows multiple read operations (gets) using a single consistent state of data.
602
636
* Also, for a high number of read operations (thousands, e.g. in loops),
603
637
* it is advised to run them in a single read transaction for efficiency reasons.
604
638
* Note that any exception thrown by the given Callable will be wrapped in a RuntimeException.
605
639
*/
640
+
606
641
public <T > T callInReadTx (Callable <T > callable ) {
607
642
Transaction tx = this .activeTx .get ();
608
643
// Only if not already set, allowing to call it recursively with first (outer) TX
@@ -611,6 +646,8 @@ public <T> T callInReadTx(Callable<T> callable) {
611
646
activeTx .set (tx );
612
647
try {
613
648
return callable .call ();
649
+ } catch (DbException e ) {
650
+ throw e ;
614
651
} catch (Exception e ) {
615
652
throw new RuntimeException ("Callable threw exception" , e );
616
653
} finally {
0 commit comments