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/01/04 20:46:17 UTC

[03/14] jena git commit: JENA-1458: Use TxnType, replacing ReadWrite mode

JENA-1458: Use TxnType, replacing ReadWrite mode


Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/ee7507df
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/ee7507df
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/ee7507df

Branch: refs/heads/master
Commit: ee7507df9fe24abcf076e449807dc8d056699392
Parents: 143ac13
Author: Andy Seaborne <an...@apache.org>
Authored: Sat Dec 30 22:57:06 2017 +0000
Committer: Andy Seaborne <an...@apache.org>
Committed: Sun Dec 31 10:53:24 2017 +0000

----------------------------------------------------------------------
 .../java/org/apache/jena/query/Dataset.java     |   7 +
 .../java/org/apache/jena/query/TxnMode.java     |  64 ----------
 .../java/org/apache/jena/query/TxnType.java     |  64 ++++++++++
 .../sparql/core/DatasetGraphTrackActive.java    |  18 ++-
 .../jena/sparql/core/DatasetGraphWithLock.java  |  11 +-
 .../jena/sparql/core/DatasetGraphWrapper.java   | 128 +++++++++++--------
 .../jena/sparql/core/DatasetGraphZero.java      |   1 +
 .../apache/jena/sparql/core/Transactional.java  |  55 ++++----
 .../jena/sparql/core/TransactionalLock.java     |  22 ++++
 .../jena/sparql/core/TransactionalMutex.java    |  14 +-
 .../sparql/core/TransactionalNotSupported.java  |  16 ++-
 .../core/TransactionalNotSupportedMixin.java    |  20 ++-
 .../jena/sparql/core/TransactionalNull.java     |  12 +-
 .../sparql/core/mem/DatasetGraphInMemory.java   |  50 ++++----
 .../jena/sparql/core/DatasetGraphSimpleMem.java |   5 +
 .../transaction/AbstractTestTransPromote.java   |  82 ++++++------
 16 files changed, 347 insertions(+), 222 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jena/blob/ee7507df/jena-arq/src/main/java/org/apache/jena/query/Dataset.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/query/Dataset.java b/jena-arq/src/main/java/org/apache/jena/query/Dataset.java
index 6f8bc0e..38b1c22 100644
--- a/jena-arq/src/main/java/org/apache/jena/query/Dataset.java
+++ b/jena-arq/src/main/java/org/apache/jena/query/Dataset.java
@@ -32,6 +32,13 @@ import org.apache.jena.sparql.util.Context ;
 
 public interface Dataset extends Transactional 
 {
+    // TEMP
+
+    @Override
+    public default void begin(TxnType type) { throw new UnsupportedOperationException("Dataset.begin(TxnType)"); }
+
+    
+    
     /** Get the default graph as a Jena Model */
     public Model getDefaultModel() ;
     

http://git-wip-us.apache.org/repos/asf/jena/blob/ee7507df/jena-arq/src/main/java/org/apache/jena/query/TxnMode.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/query/TxnMode.java b/jena-arq/src/main/java/org/apache/jena/query/TxnMode.java
deleted file mode 100644
index 494da17..0000000
--- a/jena-arq/src/main/java/org/apache/jena/query/TxnMode.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.jena.query;
-
-import org.apache.jena.sparql.JenaTransactionException;
-
-public enum TxnMode {
-    /** Transaction mode:
-     * <ul>
-     * <li>{@code WRITE}: this gaurantees a WRITE will complete if {@code commit()} is
-     * called. The same as {@code begin(ReadWrite.WRITE)}.
-     * 
-     * <li>{@code READ}: the transaction can not promote to WRITE,ensuring read-only
-     * access to the data. The same as {@code begin(ReadWrite.READ)}.
-     * 
-     * <li>{@code READ_PROMOTE}: the transaction will go from "read" to "write" if the
-     * dataset has not been modified but if it has, the promotion fails with
-     * exception.
-     * 
-     * <li>{@code READ_COMMITTED_PROMOTE}: Use this with care. The promotion will succeed but 
-     * changes from oher transactions become visible.
-     * </ul>
-     * 
-     * Read committed: at the point transaction attempts promotion from "read" to
-     * "write", the sytem checks if the datset has chnage since the trsnaction started
-     * (called {@code begin}). If {@code READ_PROMOTE}, the dataset must not have
-     * changed; if {@code READ_COMMITTED_PROMOTE} anyh intermediate changes are
-     * visible but the application can not assume any data it has read in the
-     * transaction is the same as it was at the point the transaction started.
-     */
-    READ, WRITE, READ_PROMOTE, READ_COMMITTED_PROMOTE
-    ;
-    
-    public static TxnMode convert(ReadWrite rw) {
-        switch(rw) {
-            case READ: return READ;
-            case WRITE: return WRITE;
-            default: throw new NullPointerException();
-        }
-    }
-    public static ReadWrite convert(TxnMode mode) {
-        switch(mode) {
-            case READ: return ReadWrite.READ;
-            case WRITE: return ReadWrite.WRITE;
-            default: throw new JenaTransactionException("Incompatible mode: "+mode);
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jena/blob/ee7507df/jena-arq/src/main/java/org/apache/jena/query/TxnType.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/query/TxnType.java b/jena-arq/src/main/java/org/apache/jena/query/TxnType.java
new file mode 100644
index 0000000..3679414
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/query/TxnType.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.query;
+
+import org.apache.jena.sparql.JenaTransactionException;
+
+public enum TxnType {
+    /** Transaction mode:
+     * <ul>
+     * <li>{@code WRITE}: this gaurantees a WRITE will complete if {@code commit()} is
+     * called. The same as {@code begin(ReadWrite.WRITE)}.
+     * 
+     * <li>{@code READ}: the transaction can not promote to WRITE,ensuring read-only
+     * access to the data. The same as {@code begin(ReadWrite.READ)}.
+     * 
+     * <li>{@code READ_PROMOTE}: the transaction will go from "read" to "write" if the
+     * dataset has not been modified but if it has, the promotion fails with
+     * exception.
+     * 
+     * <li>{@code READ_COMMITTED_PROMOTE}: Use this with care. The promotion will succeed but 
+     * changes from oher transactions become visible.
+     * </ul>
+     * 
+     * Read committed: at the point transaction attempts promotion from "read" to
+     * "write", the sytem checks if the datset has chnage since the trsnaction started
+     * (called {@code begin}). If {@code READ_PROMOTE}, the dataset must not have
+     * changed; if {@code READ_COMMITTED_PROMOTE} anyh intermediate changes are
+     * visible but the application can not assume any data it has read in the
+     * transaction is the same as it was at the point the transaction started.
+     */
+    READ, WRITE, READ_PROMOTE, READ_COMMITTED_PROMOTE
+    ;
+    
+    public static TxnType convert(ReadWrite rw) {
+        switch(rw) {
+            case READ: return READ;
+            case WRITE: return WRITE;
+            default: throw new NullPointerException();
+        }
+    }
+    public static ReadWrite convert(TxnType mode) {
+        switch(mode) {
+            case READ: return ReadWrite.READ;
+            case WRITE: return ReadWrite.WRITE;
+            default: throw new JenaTransactionException("Incompatible mode: "+mode);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/jena/blob/ee7507df/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphTrackActive.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphTrackActive.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphTrackActive.java
index 7e29034..ef15ea1 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphTrackActive.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphTrackActive.java
@@ -19,6 +19,7 @@
 package org.apache.jena.sparql.core;
 
 import org.apache.jena.query.ReadWrite ;
+import org.apache.jena.query.TxnType;
 
 /** Check the transactional state of a DatasetGraph */ 
 public abstract class DatasetGraphTrackActive extends DatasetGraphWrapper
@@ -35,9 +36,21 @@ public abstract class DatasetGraphTrackActive extends DatasetGraphWrapper
     protected abstract void checkNotActive() ;
     
     @Override
+    public final void begin(TxnType txnType) {
+        checkNotActive();
+        _begin(txnType);
+    }
+
+    @Override
     public final void begin(ReadWrite readWrite) {
         checkNotActive();
-        _begin(readWrite);
+        _begin(TxnType.convert(readWrite));
+    }
+
+    @Override
+    public final boolean promote() {
+        checkActive();
+        return _promote();
     }
 
     @Override
@@ -60,7 +73,8 @@ public abstract class DatasetGraphTrackActive extends DatasetGraphWrapper
     
     @Override
     public abstract boolean isInTransaction() ;
-    protected abstract void _begin(ReadWrite readWrite) ;
+    protected abstract void _begin(TxnType txnType);
+    protected abstract boolean _promote() ;
     protected abstract void _commit() ;
     protected abstract void _abort() ;
     protected abstract void _end() ;

http://git-wip-us.apache.org/repos/asf/jena/blob/ee7507df/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWithLock.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWithLock.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWithLock.java
index 8bd1d91..86ae484 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWithLock.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWithLock.java
@@ -21,6 +21,7 @@ package org.apache.jena.sparql.core ;
 import org.apache.jena.atlas.lib.Lib ;
 import org.apache.jena.atlas.lib.Sync ;
 import org.apache.jena.query.ReadWrite ;
+import org.apache.jena.query.TxnType;
 import org.apache.jena.sparql.JenaTransactionException ;
 import org.apache.jena.sparql.SystemARQ ;
 import org.apache.jena.sparql.util.Context ;
@@ -92,8 +93,9 @@ public class DatasetGraphWithLock extends DatasetGraphTrackActive implements Syn
     }
 
     @Override
-    protected void _begin(ReadWrite readWrite) {
-        transactional.begin(readWrite);
+    protected void _begin(TxnType txnType) {
+        ReadWrite readWrite = TxnType.convert(txnType);
+        transactional.begin(txnType);
         writeTxn.set(readWrite.equals(ReadWrite.WRITE));
         if ( dsChanges != null )
             // Replace by transactional state.
@@ -101,6 +103,11 @@ public class DatasetGraphWithLock extends DatasetGraphTrackActive implements Syn
     }
 
     @Override
+    protected boolean _promote() {
+        throw new JenaTransactionException("promote not supported");
+    }
+
+    @Override
     protected void _commit() {
         if ( writeTxn.get() ) {
             sync() ;

http://git-wip-us.apache.org/repos/asf/jena/blob/ee7507df/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWrapper.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWrapper.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWrapper.java
index 1f1f00b..9bb5fb9 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWrapper.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWrapper.java
@@ -18,25 +18,26 @@
 
 package org.apache.jena.sparql.core;
 
-import java.util.Iterator ;
-
-import org.apache.jena.atlas.lib.Sync ;
-import org.apache.jena.graph.Graph ;
-import org.apache.jena.graph.Node ;
-import org.apache.jena.query.ReadWrite ;
-import org.apache.jena.shared.Lock ;
-import org.apache.jena.sparql.SystemARQ ;
-import org.apache.jena.sparql.util.Context ;
+import java.util.Iterator;
+
+import org.apache.jena.atlas.lib.Sync;
+import org.apache.jena.graph.Graph;
+import org.apache.jena.graph.Node;
+import org.apache.jena.query.ReadWrite;
+import org.apache.jena.query.TxnType;
+import org.apache.jena.shared.Lock;
+import org.apache.jena.sparql.SystemARQ;
+import org.apache.jena.sparql.util.Context;
 import org.apache.jena.system.Txn;
 
 public class DatasetGraphWrapper implements DatasetGraph, Sync 
 {
     // The wrapped DatasetGraph but all calls go via get() so this can be null.
-    private final DatasetGraph dsg ;
+    private final DatasetGraph dsg;
     
     /** Return the DatasetGraph being wrapped. */
     public final DatasetGraph getWrapped() { 
-        return get() ;
+        return get();
     }
     
     /** Recursively unwrap a DatasetGraphWrapped.
@@ -44,11 +45,11 @@ public class DatasetGraphWrapper implements DatasetGraph, Sync
      * @return the first found {@link DatasetGraph} that is not an instance of {@link DatasetGraphWrapper}
      */
     public final DatasetGraph getBase() { 
-        DatasetGraph dsgw = dsg ;
+        DatasetGraph dsgw = dsg;
         while (dsgw instanceof DatasetGraphWrapper) {
-            dsgw = ((DatasetGraphWrapper)dsg).getWrapped() ;
+            dsgw = ((DatasetGraphWrapper)dsg).getWrapped();
         }
-        return dsgw ;
+        return dsgw;
     }
 
     /** The dataset to use for redirection - can be overridden.
@@ -56,27 +57,27 @@ public class DatasetGraphWrapper implements DatasetGraph, Sync
      *  delegated call.  Changes to the wrapped object can be
      *  made based on that contract. 
      */
-    protected DatasetGraph get() { return dsg ; }
+    protected DatasetGraph get() { return dsg; }
 
     /** For operations that only read the DatasetGraph. */ 
-    protected DatasetGraph getR() { return get() ; }
+    protected DatasetGraph getR() { return get(); }
     
     /** For operations that write the DatasetGraph. */ 
-    protected DatasetGraph getW() { return get() ; }
+    protected DatasetGraph getW() { return get(); }
     
     /** For operations that get a handle on a graph. */
-    protected DatasetGraph getG() { return get() ; }
+    protected DatasetGraph getG() { return get(); }
     
     /** For operations that pass on transaction actions. */
-    protected DatasetGraph getT() { return get() ; }
+    protected DatasetGraph getT() { return get(); }
 
     public DatasetGraphWrapper(DatasetGraph dsg) {
-        this.dsg = dsg ;
+        this.dsg = dsg;
     }
 
     @Override
     public boolean containsGraph(Node graphNode)
-    { return getR().containsGraph(graphNode) ; }
+    { return getR().containsGraph(graphNode); }
 
     @Override
     public Graph getDefaultGraph()
@@ -88,91 +89,91 @@ public class DatasetGraphWrapper implements DatasetGraph, Sync
 
     @Override
     public Graph getGraph(Node graphNode)
-    { return getG().getGraph(graphNode) ; }
+    { return getG().getGraph(graphNode); }
 
     @Override
     public void addGraph(Node graphName, Graph graph)
-    { getW().addGraph(graphName, graph) ; }
+    { getW().addGraph(graphName, graph); }
 
     @Override
     public void removeGraph(Node graphName)
-    { getW().removeGraph(graphName) ; }
+    { getW().removeGraph(graphName); }
 
     @Override
     public void setDefaultGraph(Graph g)
-    { getW().setDefaultGraph(g) ; }
+    { getW().setDefaultGraph(g); }
 
     @Override
     public Lock getLock()
-    { return getR().getLock() ; }
+    { return getR().getLock(); }
 
     @Override
     public Iterator<Node> listGraphNodes()
-    { return getR().listGraphNodes() ; }
+    { return getR().listGraphNodes(); }
 
     @Override
     public void add(Quad quad)
-    { getW().add(quad) ; }
+    { getW().add(quad); }
 
     @Override
     public void delete(Quad quad)
-    { getW().delete(quad) ; }
+    { getW().delete(quad); }
 
     @Override
     public void add(Node g, Node s, Node p, Node o)
-    { getW().add(g, s, p, o) ; }
+    { getW().add(g, s, p, o); }
 
     @Override
     public void delete(Node g, Node s, Node p, Node o)
-    { getW().delete(g, s, p, o) ; }
+    { getW().delete(g, s, p, o); }
     
     @Override
     public void deleteAny(Node g, Node s, Node p, Node o)
-    { getW().deleteAny(g, s, p, o) ; }
+    { getW().deleteAny(g, s, p, o); }
 
     @Override
     public void clear()
-    { getW().clear() ; }
+    { getW().clear(); }
     
     @Override
     public boolean isEmpty()
-    { return getR().isEmpty() ; }
+    { return getR().isEmpty(); }
     
     @Override
     public Iterator<Quad> find()
-    { return getR().find() ; }
+    { return getR().find(); }
 
     @Override
     public Iterator<Quad> find(Quad quad)
-    { return getR().find(quad) ; }
+    { return getR().find(quad); }
 
     @Override
     public Iterator<Quad> find(Node g, Node s, Node p, Node o)
-    { return getR().find(g, s, p, o) ; }
+    { return getR().find(g, s, p, o); }
 
     @Override
     public Iterator<Quad> findNG(Node g, Node s, Node p, Node o)
-    { return getR().findNG(g, s, p, o) ; }
+    { return getR().findNG(g, s, p, o); }
 
     @Override
     public boolean contains(Quad quad)
-    { return getR().contains(quad) ; }
+    { return getR().contains(quad); }
 
     @Override
     public boolean contains(Node g, Node s, Node p, Node o)
-    { return getR().contains(g, s, p, o) ; }
+    { return getR().contains(g, s, p, o); }
 
     @Override
     public Context getContext()
-    { return getR().getContext() ; }
+    { return getR().getContext(); }
 
     @Override
     public long size()
-    { return getR().size() ; }
+    { return getR().size(); }
 
     @Override
     public void close()
-    { getW().close() ; }
+    { getW().close(); }
     
     @Override
     public String toString() {
@@ -183,37 +184,54 @@ public class DatasetGraphWrapper implements DatasetGraph, Sync
     @Override
     public void sync() {
         // Pass down sync.
-        SystemARQ.sync(getW()) ; 
+        SystemARQ.sync(getW()); 
     }
 
     @Override
+    public void begin() { getT().begin(); }
+    
+    @Override
+    public ReadWrite transactionMode() 
+    { return getT().transactionMode(); }
+
+    @Override
+    public  TxnType transactionType() 
+    { return getT().transactionType(); }
+    
+    @Override
+    public void begin(TxnType type)
+    { getT().begin(type); }
+
+    @Override
     public void begin(ReadWrite readWrite) 
-    { getT().begin(readWrite) ; }
+    { getT().begin(readWrite); }
 
     @Override
+    public boolean promote()
+    { return getT().promote(); }
+    
+    @Override
     public void commit() 
-    { getT().commit() ; }
+    { getT().commit(); }
 
     @Override
     public void abort() 
-    { getT().abort() ; }
+    { getT().abort(); }
 
     @Override
     public void end()
-    { getT().end() ; }
+    { getT().end(); }
 
     @Override
     public boolean isInTransaction() 
-    { return get().isInTransaction() ; }    
+    { return get().isInTransaction(); }    
 
     @Override
-    public boolean supportsTransactions() {
-        return getT().supportsTransactions() ;
-    }
+    public boolean supportsTransactions() 
+    { return getT().supportsTransactions(); }
 
     @Override
-    public boolean supportsTransactionAbort() {
-        return getT().supportsTransactionAbort() ;
-    }
+    public boolean supportsTransactionAbort()
+    { return getT().supportsTransactionAbort(); }
     
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/ee7507df/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphZero.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphZero.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphZero.java
index a5a813b..6524cc9 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphZero.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphZero.java
@@ -24,6 +24,7 @@ import org.apache.jena.atlas.iterator.Iter;
 import org.apache.jena.graph.Graph;
 import org.apache.jena.graph.Node;
 import org.apache.jena.query.ReadWrite;
+import org.apache.jena.query.TxnType;
 import org.apache.jena.sparql.graph.GraphZero;
 
 /** An always empty {@link DatasetGraph}. 

http://git-wip-us.apache.org/repos/asf/jena/blob/ee7507df/jena-arq/src/main/java/org/apache/jena/sparql/core/Transactional.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/Transactional.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/Transactional.java
index f0b11d4..8425a18 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/Transactional.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/Transactional.java
@@ -19,7 +19,7 @@
 package org.apache.jena.sparql.core;
 
 import org.apache.jena.query.ReadWrite ;
-import org.apache.jena.query.TxnMode;
+import org.apache.jena.query.TxnType;
 import org.apache.jena.sparql.JenaTransactionException;
 import org.apache.jena.system.Txn;
 
@@ -62,6 +62,16 @@ import org.apache.jena.system.Txn;
 public interface Transactional 
 {
     /**
+     * Start a transaction which is READ mode and which will switch to WRITE if an update
+     * is attempted but only if no intermdiate transaction has performed an update. 
+     * <p>
+     * See {@link #begin(TxnType)} for more details an options.
+     * <p>
+     * May not be implemented. See {@link #begin(ReadWrite)} is guaranted to be provided.
+     */
+    public default void begin() { begin(TxnType.READ_PROMOTE); }
+    
+    /**
      * Start a transaction.<br/>
      * READ or WRITE transactions start in that state and do not chnage for the
      * lifetime of the transaction.
@@ -88,19 +98,17 @@ public interface Transactional
      * changed; if {@code READ_COMMITTED_PROMOTE} anyh intermediate changes are
      * visible but the application can not assume any data it has read in the
      * transaction is the same as it was at the point the transaction started.
-     */
-    //public void begin(TxnMode mode);
-    public default void begin(TxnMode mode) { begin(TxnMode.convert(mode)); }
-    
-    /**
-     * Start a transaction which is READ mode and which will switch to WRITE if an update
-     * is attempted but only if no intermdiate transaction has performed an update. 
-     * <p>
-     * See {@link #begin(TxnMode)} for more details an options.
      * <p>
-     * May not be implemented. See {@link #begin(ReadWrite)} is guaranted to be provided.
+     * This operation is optional and some implementations may throw
+     * a {@link JenaTransactionException} exception for some or all {@link TxnType} values
+     * <p> 
+     * See {@link #begin(ReadWrite)} for a form that is required of implementations.
      */
-    public default void begin() { begin(TxnMode.READ_PROMOTE); }
+    //public void begin(TxnType type);
+    public default void begin(TxnType type) { begin(TxnType.convert(type)); }
+    
+    /** Start either a READ or WRITE transaction. */ 
+    public void begin(ReadWrite readWrite) ;
     
     /**
      * Attempt to promote a transaction from "read" to "write" and the transaction
@@ -109,22 +117,9 @@ public interface Transactional
      * is still valid and in "read").
      */
     
-    // XXX OR JenaTransactionException if promote not possible.
-    
     //public void promote();
     public default boolean promote() { throw new JenaTransactionException("Not implemented"); }
-    
-    /** Return the current state of the transaction - "read" or "write" */ 
-    //public ReadWrite transactionRW();
-    public default ReadWrite transactionRW() { throw new JenaTransactionException("Not implemented"); }
-    
-    /** Return the transaction mode used in {@code begin(TxnMode)}. */ 
-    //public TxnMode transactionMode();
-    public default TxnMode transactionMode() { throw new JenaTransactionException("Not implemented"); }
-    
-    /** Start either a READ or WRITE transaction */ 
-    public void begin(ReadWrite readWrite) ;
-    
+
     /** Commit a transaction - finish the transaction and make any changes permanent (if a "write" transaction) */  
     public void commit() ;
     
@@ -134,6 +129,14 @@ public interface Transactional
     /** Finish the transaction - if a write transaction and commit() has not been called, then abort */  
     public void end() ;
 
+    /** Return the current mode of the transaction - "read" or "write" */ 
+    //public ReadWrite transactionMode();
+    public default ReadWrite transactionMode() { throw new JenaTransactionException("Not implemented"); }
+
+    /** Return the transaction type used in {@code begin(TxnType)}. */ 
+    //public TxnMode transactionMode();
+    public default TxnType transactionType() { throw new JenaTransactionException("Not implemented"); }
+
     /** Say whether inside a transaction. */ 
     public boolean isInTransaction() ;
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/ee7507df/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalLock.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalLock.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalLock.java
index 5e84b16..ad2ad3c 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalLock.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalLock.java
@@ -21,6 +21,7 @@ package org.apache.jena.sparql.core;
 import java.util.Objects ;
 
 import org.apache.jena.query.ReadWrite ;
+import org.apache.jena.query.TxnType;
 import org.apache.jena.shared.Lock ;
 import org.apache.jena.shared.LockMRPlusSW ;
 import org.apache.jena.shared.LockMRSW ;
@@ -33,7 +34,9 @@ import org.apache.jena.sparql.JenaTransactionException ;
  *  To use with implementation inheritance, for when you don't inherit:
  *  <pre>
  *      private final Transactional txn                     = TransactionalLock.createMRSW() ;
+ *      {@literal @}Override public void begin(TxnType txnType)        { txn.begin(txnType) ; }
  *      {@literal @}Override public void begin(ReadWrite mode)         { txn.begin(mode) ; }
+ *      {@literal @}Override public boolean promote()                  { return txn.promote() ; }
  *      {@literal @}Override public void commit()                      { txn.commit() ; }
  *      {@literal @}Override public void abort()                       { txn.abort() ; }
  *      {@literal @}Override public boolean isInTransaction()          { return txn.isInTransaction() ; }
@@ -83,13 +86,32 @@ public class TransactionalLock implements Transactional {
 
     @Override
     public void begin(ReadWrite readWrite) {
+        begin(TxnType.convert(readWrite));
+    }
+    
+    @Override
+    public void begin(TxnType txnType) {
         if ( isInTransaction() )
             error("Already in a transaction") ;
+        switch(txnType) {
+            case READ_PROMOTE:
+            case READ_COMMITTED_PROMOTE:
+                throw new UnsupportedOperationException("begin("+txnType+")");
+            default:
+        }
+        ReadWrite readWrite = TxnType.convert(txnType);  
         boolean isRead = readWrite.equals(ReadWrite.READ) ;
         lock.enterCriticalSection(isRead) ;
         txnMode.set(readWrite) ;
     }
 
+    // Lock propmotion required (Ok for mutex) 
+    
+//    @Override
+//    public boolean promote() { 
+//        return ??;
+//    }
+
     @Override
     public void commit() {
         endOnce() ;

http://git-wip-us.apache.org/repos/asf/jena/blob/ee7507df/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalMutex.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalMutex.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalMutex.java
index 50b2e4d..4f722c7 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalMutex.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalMutex.java
@@ -19,6 +19,7 @@
 package org.apache.jena.sparql.core;
 
 import org.apache.jena.query.ReadWrite ;
+import org.apache.jena.query.TxnType;
 import org.apache.jena.shared.Lock ;
 
 /** Transactional by mutual exclusion. */
@@ -27,17 +28,27 @@ public class TransactionalMutex implements Transactional
     private final Lock lock;
     private ThreadLocal<Boolean> isInTransaction = ThreadLocal.withInitial(()->false) ;
     
-    public TransactionalMutex(Lock lock) {
+    private TransactionalMutex(Lock lock) {
         this.lock = lock ;
     }
     
     @Override
     public void begin(ReadWrite readWrite) {
+        begin(TxnType.convert(readWrite));
+    }
+    
+    @Override
+    public void begin(TxnType txnType) {
         lock.enterCriticalSection(false);       // Always take a write lock - i.e. exclusive.
         isInTransaction.set(true); 
     }
 
     @Override
+    public boolean promote() {
+        return true;
+    }
+
+    @Override
     public void commit() {
         end() ;
     }
@@ -59,5 +70,6 @@ public class TransactionalMutex implements Transactional
             lock.leaveCriticalSection();
         }
         isInTransaction.remove();
+        isInTransaction = null;
     }
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/ee7507df/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupported.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupported.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupported.java
index 55e1571..287aabd 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupported.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupported.java
@@ -19,6 +19,7 @@
 package org.apache.jena.sparql.core;
 
 import org.apache.jena.query.ReadWrite ;
+import org.apache.jena.query.TxnType;
 
 /** Implementation for "un-Transactional" interface.
  * 
@@ -38,7 +39,9 @@ public class TransactionalNotSupported implements Transactional
     // As an included component. 
     /*
     private final Transactional txn                     = new TransactionalNotSupported() ;
+    @Override public void begin(TxnType txnType)        { txn.begin(type) ; }
     @Override public void begin(ReadWrite mode)         { txn.begin(mode) ; }
+    @Override public boolean promote()                  {  returntxn.promote() ; }
     @Override public void commit()                      { txn.commit() ; }
     @Override public void abort()                       { txn.abort() ; }
     @Override public boolean isInTransaction()          { return txn.isInTransaction() ; }
@@ -48,9 +51,20 @@ public class TransactionalNotSupported implements Transactional
     */
     
     @Override
+    public void begin()
+    { throw new UnsupportedOperationException("Transactional.begin()") ; }
+
+    @Override
+    public void begin(TxnType txnType)
+    { throw new UnsupportedOperationException("Transactional.begin(TxnType") ; }
+
+    @Override
     public void begin(ReadWrite readWrite)
-    { throw new UnsupportedOperationException("Transactional.begin") ; }
+    { throw new UnsupportedOperationException("Transactional.begin(ReadWrite)") ; }
 
+    @Override public boolean promote()
+    { throw new UnsupportedOperationException("Transactional.promote") ; }
+    
     @Override
     public void commit()
     { throw new UnsupportedOperationException("Transactional.commit") ; }

http://git-wip-us.apache.org/repos/asf/jena/blob/ee7507df/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupportedMixin.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupportedMixin.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupportedMixin.java
index b6da902..4a98044 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupportedMixin.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupportedMixin.java
@@ -19,20 +19,30 @@
 package org.apache.jena.sparql.core;
 
 import org.apache.jena.query.ReadWrite ;
+import org.apache.jena.query.TxnType;
 import org.apache.jena.shared.LockMutex ;
 
 /** Mixin interface for the "un-Transactional" interface.
  * Use with {@link LockMutex}.
- * 
- *  * 
  * @see TransactionalNotSupportedMixin
  */ 
 public interface TransactionalNotSupportedMixin extends Transactional
 {
     @Override
+    public default void begin()
+    { throw new UnsupportedOperationException("Transactional.begin()") ; }
+
+    @Override
+    public default void begin(TxnType txnType)
+    { throw new UnsupportedOperationException("Transactional.begin(TxnType") ; }
+
+    @Override
     public default void begin(ReadWrite readWrite)
     { throw new UnsupportedOperationException("Transactional.begin") ; }
 
+    @Override public default boolean promote()
+    { throw new UnsupportedOperationException("Transactional.promote") ; }
+    
     @Override
     public default void commit()
     { throw new UnsupportedOperationException("Transactional.commit") ; }
@@ -48,5 +58,11 @@ public interface TransactionalNotSupportedMixin extends Transactional
     @Override
     public default void end()
     { throw new UnsupportedOperationException("Transactional.end") ; }
+    
+    public default boolean supportsTransactions()
+    { return false ; }
+    
+    public default boolean supportsTransactionAbort()
+    { return false; }
 }
 

http://git-wip-us.apache.org/repos/asf/jena/blob/ee7507df/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNull.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNull.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNull.java
index 618ad38..822b77d 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNull.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNull.java
@@ -19,6 +19,7 @@
 package org.apache.jena.sparql.core;
 
 import org.apache.jena.query.ReadWrite;
+import org.apache.jena.query.TxnType;
 import org.apache.jena.sparql.JenaTransactionException;
 
 /**
@@ -31,14 +32,23 @@ public class TransactionalNull implements Transactional {
     
     private ThreadLocal<Boolean> inTransaction = ThreadLocal.withInitial(() -> Boolean.FALSE);
 
+
     @Override
-    public void begin(ReadWrite readWrite) {
+    public void begin(TxnType type) {
         if ( inTransaction.get() )
             throw new JenaTransactionException("Already in transaction"); 
         inTransaction.set(true);
     }
 
     @Override
+    public void begin(ReadWrite readWrite) {
+        begin(TxnType.convert(readWrite));
+    }
+
+    @Override
+    public boolean promote() { return true; } 
+    
+    @Override
     public void commit() {
         if ( ! inTransaction.get() )
             throw new JenaTransactionException("Not in transaction"); 

http://git-wip-us.apache.org/repos/asf/jena/blob/ee7507df/jena-arq/src/main/java/org/apache/jena/sparql/core/mem/DatasetGraphInMemory.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/mem/DatasetGraphInMemory.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/mem/DatasetGraphInMemory.java
index b962a8d..1905d05 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/mem/DatasetGraphInMemory.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/mem/DatasetGraphInMemory.java
@@ -37,7 +37,7 @@ import org.apache.jena.graph.Graph;
 import org.apache.jena.graph.Node;
 import org.apache.jena.graph.Triple;
 import org.apache.jena.query.ReadWrite;
-import org.apache.jena.query.TxnMode;
+import org.apache.jena.query.TxnType;
 import org.apache.jena.shared.Lock;
 import org.apache.jena.shared.LockMRPlusSW;
 import org.apache.jena.sparql.JenaTransactionException;
@@ -84,29 +84,25 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
         isInTransaction.set(b);
     }
 
-    private final ThreadLocal<TxnMode> transactionMode = withInitial(() -> null);
+    private final ThreadLocal<TxnType> transactionType = withInitial(() -> null);
     // Current state.
-    private final ThreadLocal<ReadWrite> transactionType = withInitial(() -> null);
+    private final ThreadLocal<ReadWrite> transactionMode = withInitial(() -> null);
 
     /**
-     * @return the type of transaction in progress
+     * @return the current mode of the transaction in progress
      */
-    private ReadWrite transactionType() {
-        return transactionType.get();
-    }
-
     @Override
-    public ReadWrite transactionRW() { 
-        return transactionType.get();
+    public ReadWrite transactionMode() { 
+        return transactionMode.get();
     }
     
     @Override
-    public TxnMode transactionMode() {
-        return transactionMode.get();
+    public TxnType transactionType() {
+        return transactionType.get();
     }
 
     private void transactionType(final ReadWrite readWrite) {
-        transactionType.set(readWrite);
+        transactionMode.set(readWrite);
     }
 
     private final QuadTable quadsIndex;
@@ -143,11 +139,11 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
     public boolean supportsTransactionAbort()   { return true; }
 
     @Override
-    public void begin(TxnMode txnMode) {
+    public void begin(TxnType txnType) {
         if (isInTransaction()) 
             throw new JenaTransactionException("Transactions cannot be nested!");
-        transactionMode.set(txnMode);
-        ReadWrite initial = txnMode.equals(TxnMode.WRITE) ? WRITE : READ;
+        transactionType.set(txnType);
+        ReadWrite initial = txnType.equals(TxnType.WRITE) ? WRITE : READ;
         _begin(initial);
     }
     
@@ -155,7 +151,7 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
     public void begin(final ReadWrite readWrite) {
         if (isInTransaction()) 
             throw new JenaTransactionException("Transactions cannot be nested!");
-        transactionMode.set(TxnMode.convert(readWrite));
+        transactionType.set(TxnType.convert(readWrite));
         _begin(readWrite) ;
     }
 
@@ -178,8 +174,8 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
     /** Called transaction ending code at most once per transaction. */ 
     private void finishTransaction() {
         isInTransaction.remove();
-        transactionMode.remove();
         transactionType.remove();
+        transactionMode.remove();
         version.remove();
         transactionLock.leaveCriticalSection();
     }
@@ -188,12 +184,12 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
     public boolean promote() {
         if (!isInTransaction())
             throw new JenaTransactionException("Tried to promote outside a transaction!");
-        if ( transactionType().equals(ReadWrite.WRITE) )
+        if ( transactionMode().equals(ReadWrite.WRITE) )
             return true;
 
         boolean readCommitted;
         // Initial state
-        switch(transactionMode.get()) {
+        switch(transactionType.get()) {
             case WRITE :
                 return true;
             case READ :
@@ -252,7 +248,7 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
     public void commit() {
         if (!isInTransaction())
             throw new JenaTransactionException("Tried to commit outside a transaction!");
-        if (transactionType().equals(WRITE))
+        if (transactionMode().equals(WRITE))
             _commit();
         finishTransaction();
     }
@@ -264,7 +260,7 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
             quadsIndex().end();
             defaultGraph().end();
 
-            if ( transactionType().equals(WRITE) ) {
+            if ( transactionMode().equals(WRITE) ) {
                 if ( version.get() != generation.get() )
                     throw new InternalErrorException(String.format("Version=%d, Generation=%d",version.get(),generation.get())) ;
                 generation.incrementAndGet() ;
@@ -276,7 +272,7 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
     public void abort() {
         if (!isInTransaction()) 
             throw new JenaTransactionException("Tried to abort outside a transaction!");
-        if (transactionType().equals(WRITE))
+        if (transactionMode().equals(WRITE))
             _abort();
         finishTransaction();
     }
@@ -299,7 +295,7 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
     @Override
     public void end() {
         if (isInTransaction()) {
-            if (transactionType().equals(WRITE)) {
+            if (transactionMode().equals(WRITE)) {
                 String msg = "end() called for WRITE transaction without commit or abort having been called. This causes a forced abort.";
                 // _abort does _end actions inside the lock. 
                 _abort() ;
@@ -413,8 +409,8 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
             }
             return ;
         }
-        if ( !transactionType().equals(WRITE) ) {
-            TxnMode mode = transactionMode.get();
+        if ( !transactionMode().equals(WRITE) ) {
+            TxnType mode = transactionType.get();
             switch(mode) {
                 case WRITE :
                     break;
@@ -423,7 +419,7 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
                 case READ_COMMITTED_PROMOTE :
                 case READ_PROMOTE :
                 {
-                    boolean readCommitted = (mode == TxnMode.READ_COMMITTED_PROMOTE);
+                    boolean readCommitted = (mode == TxnType.READ_COMMITTED_PROMOTE);
                     _promote(readCommitted);
                     break;
                 }

http://git-wip-us.apache.org/repos/asf/jena/blob/ee7507df/jena-arq/src/test/java/org/apache/jena/sparql/core/DatasetGraphSimpleMem.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/core/DatasetGraphSimpleMem.java b/jena-arq/src/test/java/org/apache/jena/sparql/core/DatasetGraphSimpleMem.java
index e5631af..48ca221 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/core/DatasetGraphSimpleMem.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/core/DatasetGraphSimpleMem.java
@@ -239,4 +239,9 @@ public class DatasetGraphSimpleMem extends DatasetGraphTriplesQuads implements T
     @Override
     public void close()
     {}
+
+    @Override
+    public boolean supportsTransactionAbort() {
+        return false;
+    }
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/ee7507df/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransPromote.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransPromote.java b/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransPromote.java
index 421964d..e2d2237 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransPromote.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransPromote.java
@@ -27,7 +27,7 @@ import java.util.concurrent.atomic.AtomicInteger ;
 import org.apache.jena.atlas.iterator.Iter ;
 import org.apache.jena.atlas.lib.Lib ;
 import org.apache.jena.query.ReadWrite ;
-import org.apache.jena.query.TxnMode;
+import org.apache.jena.query.TxnType;
 import org.apache.jena.sparql.JenaTransactionException;
 import org.apache.jena.sparql.core.DatasetGraph ;
 import org.apache.jena.sparql.core.Quad ;
@@ -139,68 +139,68 @@ public abstract class AbstractTestTransPromote {
 
     // Subclass / parameterized
     
-    @Test public void promote_snapshot_01()         { run_01(TxnMode.READ_PROMOTE) ; }
-    @Test public void promote_readCommitted_01()    { run_01(TxnMode.READ_COMMITTED_PROMOTE) ; }
+    @Test public void promote_snapshot_01()         { run_01(TxnType.READ_PROMOTE) ; }
+    @Test public void promote_readCommitted_01()    { run_01(TxnType.READ_COMMITTED_PROMOTE) ; }
     
     // READ-add
-    private void run_01(TxnMode txnMode) {
+    private void run_01(TxnType txnType) {
         Assume.assumeTrue( supportsReadCommitted() );
         DatasetGraph dsg = create() ;
-        dsg.begin(txnMode) ;
+        dsg.begin(txnType) ;
         dsg.add(q1) ;
         dsg.commit() ;
         dsg.end() ;
     }
     
-    @Test public void promote_snapshot_02()         { run_02(TxnMode.READ_PROMOTE) ; }
-    @Test public void promote_readCommitted_02()    { run_02(TxnMode.READ_COMMITTED_PROMOTE) ; }
+    @Test public void promote_snapshot_02()         { run_02(TxnType.READ_PROMOTE) ; }
+    @Test public void promote_readCommitted_02()    { run_02(TxnType.READ_COMMITTED_PROMOTE) ; }
     
     // Previous transaction then READ-add
-    private void run_02(TxnMode txnMode) {
+    private void run_02(TxnType txnType) {
         DatasetGraph dsg = create() ;
         
-        dsg.begin(txnMode) ;dsg.end() ;
+        dsg.begin(txnType) ;dsg.end() ;
         
-        dsg.begin(txnMode) ;
+        dsg.begin(txnType) ;
         dsg.add(q1) ;
         dsg.commit() ;
         dsg.end() ;
     }
     
-    @Test public void promote_snapshot_03()         { run_03(TxnMode.READ_PROMOTE) ; }
-    @Test public void promote_readCommitted_03()    { run_03(TxnMode.READ_COMMITTED_PROMOTE) ; }
+    @Test public void promote_snapshot_03()         { run_03(TxnType.READ_PROMOTE) ; }
+    @Test public void promote_readCommitted_03()    { run_03(TxnType.READ_COMMITTED_PROMOTE) ; }
 
-    private void run_03(TxnMode txnMode) {
+    private void run_03(TxnType txnType) {
         DatasetGraph dsg = create() ;
         
-        dsg.begin(TxnMode.WRITE) ;dsg.commit() ; dsg.end() ;
+        dsg.begin(TxnType.WRITE) ;dsg.commit() ; dsg.end() ;
         
-        dsg.begin(txnMode) ;
+        dsg.begin(txnType) ;
         dsg.add(q1) ;
         dsg.commit() ;
         dsg.end() ;
     }
     
-    @Test public void promote_snapshot_04()         { run_04(TxnMode.READ_PROMOTE) ; }
-    @Test public void promote_readCommitted_04()    { run_04(TxnMode.READ_COMMITTED_PROMOTE) ; }
+    @Test public void promote_snapshot_04()         { run_04(TxnType.READ_PROMOTE) ; }
+    @Test public void promote_readCommitted_04()    { run_04(TxnType.READ_COMMITTED_PROMOTE) ; }
 
-    private void run_04(TxnMode txnMode) {
+    private void run_04(TxnType txnType) {
         DatasetGraph dsg = create() ;
         
         dsg.begin(ReadWrite.WRITE) ;dsg.abort() ; dsg.end() ;
         
-        dsg.begin(txnMode) ;
+        dsg.begin(txnType) ;
         dsg.add(q1) ;
         dsg.commit() ;
         dsg.end() ;
     }
 
-    @Test public void promote_snapshot_05()         { run_05(TxnMode.READ_PROMOTE) ; }
-    @Test public void promote_readCommitted_05()    { run_05(TxnMode.READ_COMMITTED_PROMOTE) ; }
+    @Test public void promote_snapshot_05()         { run_05(TxnType.READ_PROMOTE) ; }
+    @Test public void promote_readCommitted_05()    { run_05(TxnType.READ_COMMITTED_PROMOTE) ; }
     
-    private void run_05(TxnMode txnMode) {
+    private void run_05(TxnType txnType) {
         DatasetGraph dsg = create() ;
-        dsg.begin(txnMode) ;
+        dsg.begin(txnType) ;
         dsg.add(q1) ;
         
         try {
@@ -216,7 +216,7 @@ public abstract class AbstractTestTransPromote {
     //@Test public void promote_readCommitted_06()    { run_06(TxnMode.READ_COMMITTED_PROMOTE) ; }
     
     // Async writer after promotion.
-    private void run_06(TxnMode txnMode) {
+    private void run_06(TxnType txnType) {
         DatasetGraph dsg = create() ;
         AtomicInteger a = new AtomicInteger(0) ;
 
@@ -227,7 +227,7 @@ public abstract class AbstractTestTransPromote {
             sema.release() ;
         }) ;
 
-        dsg.begin(txnMode) ;
+        dsg.begin(txnType) ;
         // Promote
         dsg.add(q1) ;
         t.start() ;
@@ -243,11 +243,11 @@ public abstract class AbstractTestTransPromote {
         assertCount(3, dsg) ;
     }
 
-    @Test public void promote_snapshot_07()         { run_07(TxnMode.READ_PROMOTE) ; }
-    @Test public void promote_readCommitted_07()    { run_07(TxnMode.READ_COMMITTED_PROMOTE) ; }
+    @Test public void promote_snapshot_07()         { run_07(TxnType.READ_PROMOTE) ; }
+    @Test public void promote_readCommitted_07()    { run_07(TxnType.READ_COMMITTED_PROMOTE) ; }
     
     // Async writer after promotion.
-    private void run_07(TxnMode txnMode) {
+    private void run_07(TxnType txnType) {
         DatasetGraph dsg = create() ;
         // Start long running reader.
         ThreadAction tt = ThreadTxn.threadTxnRead(dsg, () -> {
@@ -257,7 +257,7 @@ public abstract class AbstractTestTransPromote {
         }) ;
 
         // Start R->W here
-        dsg.begin(txnMode) ;
+        dsg.begin(txnType) ;
         dsg.add(q1) ;
         dsg.add(q2) ;
         dsg.commit() ;
@@ -265,14 +265,14 @@ public abstract class AbstractTestTransPromote {
         tt.run() ;
     }
     
-    @Test public void promote_snapshot_08()         { run_08(TxnMode.READ_PROMOTE); }
-    @Test public void promote_readCommitted_08()    { run_08(TxnMode.READ_COMMITTED_PROMOTE) ; }
+    @Test public void promote_snapshot_08()         { run_08(TxnType.READ_PROMOTE); }
+    @Test public void promote_readCommitted_08()    { run_08(TxnType.READ_COMMITTED_PROMOTE) ; }
     
     // Async writer after promotion trasnaction ends.
-    private void run_08(TxnMode txnMode) {
+    private void run_08(TxnType txnType) {
         DatasetGraph dsg = create() ;
         // Start R->W here
-        dsg.begin(txnMode) ;
+        dsg.begin(txnType) ;
         dsg.add(q1) ;
         dsg.add(q2) ;
         dsg.commit() ;
@@ -284,14 +284,14 @@ public abstract class AbstractTestTransPromote {
     }
 
     @Test
-    public void promote_10() { promote_readCommit_txnCommit(TxnMode.READ_COMMITTED_PROMOTE, true) ; }
+    public void promote_10() { promote_readCommit_txnCommit(TxnType.READ_COMMITTED_PROMOTE, true) ; }
 
     @Test
-    public void promote_11() { promote_readCommit_txnCommit(TxnMode.READ_COMMITTED_PROMOTE, false) ; }
+    public void promote_11() { promote_readCommit_txnCommit(TxnType.READ_COMMITTED_PROMOTE, false) ; }
     
     @Test
     public void promote_12() { 
-        expect(()->promote_readCommit_txnCommit(TxnMode.READ_PROMOTE, true) ,
+        expect(()->promote_readCommit_txnCommit(TxnType.READ_PROMOTE, true) ,
                getTransactionExceptionClass()) ;
     }
     
@@ -310,22 +310,22 @@ public abstract class AbstractTestTransPromote {
     }
 
     @Test
-    public void promote_13() { promote_readCommit_txnCommit(TxnMode.READ_PROMOTE, false) ; }
+    public void promote_13() { promote_readCommit_txnCommit(TxnType.READ_PROMOTE, false) ; }
 
-    private void promote_readCommit_txnCommit(TxnMode txnMode, boolean asyncCommit) {
+    private void promote_readCommit_txnCommit(TxnType txnType, boolean asyncCommit) {
         DatasetGraph dsg = create() ;
         
         ThreadAction tt = asyncCommit?
             ThreadTxn.threadTxnWrite(dsg, () -> dsg.add(q3) ) :
             ThreadTxn.threadTxnWriteAbort(dsg, () -> dsg.add(q3)) ;
 
-        dsg.begin(txnMode) ;
+        dsg.begin(txnType) ;
         // Other runs
         tt.run() ;
         // Can promote if readCommited
         // Can't promote if not readCommited
         dsg.add(q1) ;
-        if ( txnMode == TxnMode.READ_PROMOTE && asyncCommit )
+        if ( txnType == TxnType.READ_PROMOTE && asyncCommit )
             fail("Should not be here") ;
         // read commited - we should see the ThreadAction change.
         assertEquals(asyncCommit, dsg.contains(q3)) ;
@@ -387,7 +387,7 @@ public abstract class AbstractTestTransPromote {
         semaActiveWriterStart.acquireUninterruptibly(); 
 
         Callable<RuntimeException> attemptedPromote = ()->{
-            dsg.begin(TxnMode.READ_PROMOTE) ;
+            dsg.begin(TxnType.READ_PROMOTE) ;
             semaPromoteTxnStart.release(1) ;
             // (*2)
             semaPromoteTxnContinue.acquireUninterruptibly();