@@ -210,7 +210,7 @@ private static void verifyNotAlreadyOpen(String canonicalPath) {
210210 }
211211 }
212212 if (!openFiles .add (canonicalPath )) {
213- throw new DbException ("Another BoxStore is still open for this directory: " + canonicalPath +
213+ throw new DbException ("Another BoxStore is still open for this directory: " + canonicalPath +
214214 ". Hint: for most apps it's recommended to keep a BoxStore for the app's life time." );
215215 }
216216 }
@@ -492,6 +492,43 @@ public void runInReadTx(Runnable runnable) {
492492 }
493493 }
494494
495+ /**
496+ * Calls the given callable inside a read(-only) transaction. Multiple read transactions can occur at the same time.
497+ * This allows multiple read operations (gets) using a single consistent state of data.
498+ * Also, for a high number of read operations (thousands, e.g. in loops),
499+ * it is advised to run them in a single read transaction for efficiency reasons.
500+ * Note that any exception thrown by the given Callable will be wrapped in a RuntimeException.
501+ */
502+ public <T > T callInReadTx (Callable <T > callable ) {
503+ Transaction tx = this .activeTx .get ();
504+ // Only if not already set, allowing to call it recursively with first (outer) TX
505+ if (tx == null ) {
506+ tx = beginReadTx ();
507+ activeTx .set (tx );
508+ try {
509+ return callable .call ();
510+ } catch (Exception e ) {
511+ throw new RuntimeException ("Callable threw exception" , e );
512+ } finally {
513+ activeTx .remove ();
514+
515+ // TODO That's rather a quick fix, replace with a more general solution
516+ // (that could maybe be a TX listener with abort callback?)
517+ for (Box box : boxes .values ()) {
518+ box .readTxFinished (tx );
519+ }
520+
521+ tx .close ();
522+ }
523+ } else {
524+ try {
525+ return callable .call ();
526+ } catch (Exception e ) {
527+ throw new RuntimeException ("Callable threw exception" , e );
528+ }
529+ }
530+ }
531+
495532 /**
496533 * Like {@link #runInTx(Runnable)}, but allows returning a value and throwing an exception.
497534 */
0 commit comments