private static ThreadAction create(Transactional trans, TxnType txnType, Runnable action, boolean isCommitBefore, boolean isCommitAfter) { return ThreadAction.create ( beforeAction(trans, txnType, isCommitBefore) , action , afterAction(trans, txnType, isCommitAfter) ) ; }
/** Create a thread-backed delayed READ transaction action. * Call {@link ThreadAction#run} to perform the read transaction. */ public static ThreadAction threadTxnRead(Transactional trans, Runnable action) { return threadTxn(trans, TxnType.READ, action) ; }
/** Return the current value in a transaction. * Must be inside a transaction. * @see #get */ public long read() { checkTxn(); return getDataState().txnValue; }
@Test public void txnThread_12() { long x1 = counter.get() ; ThreadAction t = ThreadTxn.threadTxnRead(counter, () -> { long z1 = counter.get() ; assertEquals("Thread", x1, z1) ; }) ; Txn.executeWrite(counter, ()->counter.inc()) ; t.run() ; long x2 = counter.get() ; assertEquals("after", x1+1, x2) ; }
@Test(expected=ExceptionFromTest.class) public void txn_exception_01() { Txn.executeWrite(counter, counter::inc) ; Txn.executeWrite(counter, () -> { counter.inc() ; assertEquals("In W, value()", 1, counter.value()) ; assertEquals("In W, get()",2, counter.get()) ; throw new ExceptionFromTest() ; }) ; }
@Test public void txn_threaded_01() { Txn.exec(counter, TxnType.READ_PROMOTE, ()->{ ThreadAction a = ThreadTxn.threadTxnWrite(counter, ()->{}); a.run(); // Blocks promotion. boolean b = counter.promote(); assertFalse(b); assertEquals(ReadWrite.READ, counter.transactionMode()); }); }
/** Execute the Runnable in a write transaction */ public static <T extends Transactional> void executeWrite(T txn, Runnable r) { exec(txn, TxnType.WRITE, r); }
/** Increment the value inside a write transaction */ public void inc() { checkWriteTxn(); IntegerState ts = getDataState(); ts.txnValue++; }
/** Create a {@code ThreadAction}. * @param action The main action run when {@link #run()} called. * @return ThreadAction */ public static ThreadAction create(Runnable action) { return create(null, action, null) ; }
@Override public void begin(TxnType txnType) { begin(txnType, true); }
/** Create a thread-backed delayed transaction action. * Call {@link ThreadAction#run} to perform the read transaction. */ public static ThreadAction threadTxn(Transactional trans, TxnType txnType, Runnable action) { return create(trans, txnType, action, true, true) ; }
/** Execute and return a value in a read transaction */ public static <T extends Transactional, X> X calculateRead(T txn, Supplier<X> r) { return calc(txn, TxnType.READ, r); }
@Test(expected=JenaTransactionException.class) public void txn_nested_12() { Txn.exec(counter, TxnType.READ_PROMOTE, ()->{ // Block promote by doing a W txn on another thread. ThreadAction.create( ()->Txn.executeWrite(counter, ()->counter.inc()) ).run(); // Can not promote outer. Txn.exec(counter, TxnType.WRITE, ()->{}); }); }
/** Set the value inside a write transaction, return the old value*/ public long set(long x) { checkWriteTxn(); IntegerState ts = getDataState(); long v = ts.txnValue; ts.txnValue = x; return v; }
/** Create a thread-backed delayed WRITE action. * Call {@link ThreadAction#run} to perform the write transaction. * (If called from inside a write transaction on the {@code trans}, * this will deadlock.) */ public static ThreadAction threadTxnWrite(Transactional trans, Runnable action) { return threadTxn(trans, TxnType.WRITE, action) ; }
/** Create a thread-backed delayed WRITE-abort action (mainly for testing). */ public static ThreadAction threadTxnWriteAbort(Transactional trans, Runnable action) { return create(trans, TxnType.WRITE, action, true, false) ; }
/** Execute and return a value in a write transaction. */ public static <T extends Transactional, X> X calculateWrite(T txn, Supplier<X> r) { return calc(txn, TxnType.WRITE, r); }
/** Decrement the value inside a write transaction */ public void dec() { checkWriteTxn(); IntegerState ts = getDataState(); ts.txnValue--; }