You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2018/05/04 08:40:46 UTC
[5/9] jena git commit: JENA-1539: Txn nesting compatibility
JENA-1539: Txn nesting compatibility
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/dbce176a
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/dbce176a
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/dbce176a
Branch: refs/heads/master
Commit: dbce176ad7f9a422198c24f8b7b79cb3c1fe5d9f
Parents: 52377b8
Author: Andy Seaborne <an...@apache.org>
Authored: Sun Apr 29 17:22:31 2018 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sun Apr 29 17:22:31 2018 +0100
----------------------------------------------------------------------
.../main/java/org/apache/jena/system/Txn.java | 45 ++++++++++-----
.../java/org/apache/jena/system/TestTxn.java | 61 ++++++++++++++++----
.../apache/jena/system/TestTxnLifecycle.java | 3 +-
3 files changed, 83 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/dbce176a/jena-arq/src/main/java/org/apache/jena/system/Txn.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/system/Txn.java b/jena-arq/src/main/java/org/apache/jena/system/Txn.java
index dc7158b..4ab2c82 100644
--- a/jena-arq/src/main/java/org/apache/jena/system/Txn.java
+++ b/jena-arq/src/main/java/org/apache/jena/system/Txn.java
@@ -18,6 +18,7 @@
package org.apache.jena.system;
+import java.util.Objects;
import java.util.function.Supplier ;
import org.apache.jena.query.TxnType;
@@ -71,12 +72,9 @@ public class Txn {
/** Execute application code in a transaction with the given {@link TxnType trasnaction type}. */
public static <T extends Transactional> void exec(T txn, TxnType txnType, Runnable r) {
boolean b = txn.isInTransaction() ;
- if ( b ) {
- TxnType txnTypeOuter = txn.transactionType();
- if ( txnTypeOuter != txnType )
- throw new JenaTransactionException("Already in a transaction of a different type: "
- +"outer="+txnTypeOuter+" : inner="+txnType);
- } else
+ if ( b )
+ checkCompatible(txn, txnType);
+ else
txn.begin(txnType) ;
try { r.run() ; }
catch (Throwable th) {
@@ -94,14 +92,10 @@ public class Txn {
/** Execute and return a value in a transaction with the given {@link TxnType trasnaction type}. */
public static <T extends Transactional, X> X calc(T txn, TxnType txnType, Supplier<X> r) {
boolean b = txn.isInTransaction() ;
- if ( b ) {
- TxnType txnTypeOuter = txn.transactionType();
- if ( txnTypeOuter != txnType )
- throw new JenaTransactionException("Already in a transaction of a different type: "
- +"outer="+txnTypeOuter+" : inner="+txnType);
- } else
+ if ( b )
+ checkCompatible(txn, txnType);
+ else
txn.begin(txnType) ;
-
X x;
try { x = r.get() ; }
catch (Throwable th) {
@@ -138,6 +132,31 @@ public class Txn {
return calc(txn, TxnType.WRITE, r);
}
+ /** Check the requested transaction {@code innerTxnType} is compatible with the transactional.
+ * @param txn
+ * @param innerTxnType
+ */
+ private static void checkCompatible(Transactional txn, TxnType innerTxnType) {
+ TxnType outerTxnType = txn.transactionType();
+ if ( outerTxnType == null )
+ // Not in an outer transaction.
+ return;
+ // innerTxnType must be "less than or equal to the outer.
+ // Inner is READ works with any outer.
+ // Outer is WRITE works with any inner.
+ // Must match:
+ // Outer is READ, then inner must be READ.
+ // Promotion must be the same.
+ if ( TxnType.READ.equals(innerTxnType) )
+ return;
+ if ( TxnType.WRITE.equals(outerTxnType) )
+ return;
+ if ( Objects.equals(innerTxnType, outerTxnType) )
+ return;
+ throw new JenaTransactionException("Already in a transaction of an incompatable type: "
+ +"outer="+outerTxnType+" : inner="+innerTxnType);
+ }
+
// Attempt some kind of cleanup.
private static <T extends Transactional> void onThrowable(Throwable th, T txn) {
try {
http://git-wip-us.apache.org/repos/asf/jena/blob/dbce176a/jena-arq/src/test/java/org/apache/jena/system/TestTxn.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/system/TestTxn.java b/jena-arq/src/test/java/org/apache/jena/system/TestTxn.java
index 668efb5..901b9c6 100644
--- a/jena-arq/src/test/java/org/apache/jena/system/TestTxn.java
+++ b/jena-arq/src/test/java/org/apache/jena/system/TestTxn.java
@@ -242,23 +242,36 @@ public class TestTxn {
});
}
- @Test(expected=JenaTransactionException.class)
+ @Test
public void txn_nested_02() {
- Txn.exec(counter, TxnType.READ, ()->{
- Txn.exec(counter, TxnType.WRITE, ()->{});
+ Txn.exec(counter, TxnType.WRITE, ()->{
+ Txn.exec(counter, TxnType.READ, ()->{});
});
}
- @Test(expected=JenaTransactionException.class)
+ @Test
public void txn_nested_03() {
- Txn.exec(counter, TxnType.WRITE, ()->{
- // Must the same type to nest Txn.
+ Txn.exec(counter, TxnType.READ_PROMOTE, ()->{
Txn.exec(counter, TxnType.READ, ()->{});
});
}
@Test
public void txn_nested_04() {
+ Txn.exec(counter, TxnType.READ_COMMITTED_PROMOTE, ()->{
+ Txn.exec(counter, TxnType.READ, ()->{});
+ });
+ }
+
+ @Test(expected=JenaTransactionException.class)
+ public void txn_nested_05() {
+ Txn.exec(counter, TxnType.READ, ()->{
+ Txn.exec(counter, TxnType.WRITE, ()->{});
+ });
+ }
+
+ @Test
+ public void txn_nested_06() {
Txn.exec(counter, TxnType.READ_PROMOTE, ()->{
boolean b = counter.promote();
assertTrue(b);
@@ -268,23 +281,49 @@ public class TestTxn {
}
@Test
- public void txn_nested_05() {
- Txn.exec(counter, TxnType.READ_PROMOTE, ()->{
+ public void txn_nested_07() {
+ Txn.exec(counter, TxnType.READ_COMMITTED_PROMOTE, ()->{
+ boolean b = counter.promote();
+ assertTrue(b);
+ // Must the same type to nest Txn.
+ Txn.exec(counter, TxnType.READ_COMMITTED_PROMOTE, ()->{});
+ });
+ }
+
+ @Test
+ public void txn_nested_08() {
+ Txn.exec(counter, TxnType.READ_COMMITTED_PROMOTE, ()->{
boolean b = counter.promote();
assertTrue(b);
assertEquals(ReadWrite.WRITE, counter.transactionMode());
// Must the same type to nest Txn.
- Txn.exec(counter, TxnType.READ_PROMOTE, ()->{});
+ Txn.exec(counter, TxnType.READ_COMMITTED_PROMOTE, ()->{});
});
}
- @Test(expected=JenaTransactionException.class)
- public void txn_nested_06() {
+ @Test
+ public void txn_nested_09() {
Txn.exec(counter, TxnType.READ_PROMOTE, ()->{
boolean b = counter.promote();
assertTrue(b);
assertEquals(ReadWrite.WRITE, counter.transactionMode());
// Must the same type to nest Txn.
+ Txn.exec(counter, TxnType.READ_PROMOTE, ()->{});
+ });
+ }
+
+ @Test(expected=JenaTransactionException.class)
+ public void txn_nested_10() {
+ Txn.exec(counter, TxnType.READ_PROMOTE, ()->{
+ // Must the same type to nest Txn.
+ Txn.exec(counter, TxnType.WRITE, ()->{});
+ });
+ }
+
+ @Test(expected=JenaTransactionException.class)
+ public void txn_nested_11() {
+ Txn.exec(counter, TxnType.READ_COMMITTED_PROMOTE, ()->{
+ // Must the same type to nest Txn.
Txn.exec(counter, TxnType.WRITE, ()->{});
});
}
http://git-wip-us.apache.org/repos/asf/jena/blob/dbce176a/jena-arq/src/test/java/org/apache/jena/system/TestTxnLifecycle.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/system/TestTxnLifecycle.java b/jena-arq/src/test/java/org/apache/jena/system/TestTxnLifecycle.java
index 76ae02e..bf65468 100644
--- a/jena-arq/src/test/java/org/apache/jena/system/TestTxnLifecycle.java
+++ b/jena-arq/src/test/java/org/apache/jena/system/TestTxnLifecycle.java
@@ -72,10 +72,9 @@ public class TestTxnLifecycle {
assertEquals(56,x) ;
}
- @Test(expected=JenaTransactionException.class)
+ @Test
public void txn_lifecycle_05b() {
int x = Txn.calculateWrite(trans, ()-> {
- // Does not continue outer transaction.
return Txn.calculateRead(trans, ()->56) ;
});
assertEquals(56,x) ;