Merge pull request #662 from afs/jena-1806-examples

JENA-1806: Update examples
diff --git a/jena-arq/src-examples/arq/examples/aggregates/CustomAggregate.java b/jena-arq/src-examples/arq/examples/aggregates/CustomAggregate.java
index 3ab2eb0..3efb081 100644
--- a/jena-arq/src-examples/arq/examples/aggregates/CustomAggregate.java
+++ b/jena-arq/src-examples/arq/examples/aggregates/CustomAggregate.java
@@ -40,7 +40,7 @@
  * <p>
  * Custom aggregates must be registered before parsing the query; custom
  * aggregates and custom functions have the same syntax so the to tell the
- * differenc, the parser needs to know which IRIs are custom aggregates.
+ * difference, the parser needs to know which IRIs are custom aggregates.
  * <p>
  * The aggregate is registered as a URI, AccumulatorFactory and default value
  * for the "no groups" case.
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 3ecb649..9242bd3 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
@@ -27,7 +27,7 @@
  * <p>
  * Nested transaction are not supported but calling inside an existing transaction, 
  * which must be compatible, (i.e. a write needs a WRITE transaction).
- * causes the exising transaction to be used.
+ * causes the existing transaction to be used.
  */
 
 public class Txn {
diff --git a/jena-core/src-examples/jena/examples/ontology/classHierarchy/ClassHierarchy.java b/jena-core/src-examples/jena/examples/ontology/classHierarchy/ClassHierarchy.java
index 88a6f84..69ec855 100644
--- a/jena-core/src-examples/jena/examples/ontology/classHierarchy/ClassHierarchy.java
+++ b/jena-core/src-examples/jena/examples/ontology/classHierarchy/ClassHierarchy.java
@@ -21,16 +21,18 @@
 package jena.examples.ontology.classHierarchy;
 
 
-// Imports
-///////////////
-import org.apache.jena.ontology.*;
-import org.apache.jena.rdf.model.*;
-import org.apache.jena.shared.PrefixMapping;
-import org.apache.jena.util.iterator.Filter;
-
 import java.io.PrintStream;
 import java.util.*;
 
+// Imports
+///////////////
+import org.apache.jena.ontology.OntClass;
+import org.apache.jena.ontology.OntModel;
+import org.apache.jena.ontology.Restriction;
+import org.apache.jena.rdf.model.AnonId;
+import org.apache.jena.rdf.model.Resource;
+import org.apache.jena.shared.PrefixMapping;
+
 
 /**
  * <p>
@@ -65,11 +67,7 @@
     public void showHierarchy( PrintStream out, OntModel m ) {
         // create an iterator over the root classes that are not anonymous class expressions
         Iterator<OntClass> i = m.listHierarchyRootClasses()
-                      .filterDrop( new Filter<OntClass>() {
-                                    @Override
-                                    public boolean accept( OntClass r ) {
-                                        return r.isAnon();
-                                    }} );
+                      .filterDrop( OntClass::isAnon );
 
         while (i.hasNext()) {
             showClass( out, i.next(), new ArrayList<OntClass>(), 0 );
diff --git a/jena-sdb/src-examples/sdb/examples/Ex1.java b/jena-sdb/src-examples/sdb/examples/Ex1.java
index 40fbbde..fd13b92 100644
--- a/jena-sdb/src-examples/sdb/examples/Ex1.java
+++ b/jena-sdb/src-examples/sdb/examples/Ex1.java
@@ -43,13 +43,12 @@
         // The right answers will be obtained but slowly.
         
         Dataset ds = DatasetStore.create(store) ;
-        QueryExecution qe = QueryExecutionFactory.create(query, ds) ;
-        try {
+        try ( QueryExecution qe = QueryExecutionFactory.create(query, ds) ) {
             ResultSet rs = qe.execSelect() ;
             ResultSetFormatter.out(rs) ;
-        } finally { qe.close() ; }
+        }
         
-        // Close the SDB conenction which also closes the underlying JDBC connection.
+        // Close the SDB connection which also closes the underlying JDBC connection.
         store.getConnection().close() ;
         store.close() ;
     }
diff --git a/jena-sdb/src-examples/sdb/examples/Ex2.java b/jena-sdb/src-examples/sdb/examples/Ex2.java
index 7410941..2d33cce 100644
--- a/jena-sdb/src-examples/sdb/examples/Ex2.java
+++ b/jena-sdb/src-examples/sdb/examples/Ex2.java
@@ -51,11 +51,10 @@
         Store store = SDBFactory.connectStore(conn, storeDesc) ;
         
         Dataset ds = DatasetStore.create(store) ;
-        QueryExecution qe = QueryExecutionFactory.create(query, ds) ;
-        try {
+        try ( QueryExecution qe = QueryExecutionFactory.create(query, ds) ) {
             ResultSet rs = qe.execSelect() ;
             ResultSetFormatter.out(rs) ;
-        } finally { qe.close() ; }
+        }
         store.close() ;
     }
 }
diff --git a/jena-sdb/src-examples/sdb/examples/ExJdbcConnection.java b/jena-sdb/src-examples/sdb/examples/ExJdbcConnection.java
index 0f2baea..f99ea4b 100644
--- a/jena-sdb/src-examples/sdb/examples/ExJdbcConnection.java
+++ b/jena-sdb/src-examples/sdb/examples/ExJdbcConnection.java
@@ -73,11 +73,10 @@
         Store store = StoreFactory.create(storeDesc, conn) ;
         
         Dataset ds = DatasetStore.create(store) ;
-        QueryExecution qe = QueryExecutionFactory.create(query, ds) ;
-        try {
+        try ( QueryExecution qe = QueryExecutionFactory.create(query, ds) ) {
             ResultSet rs = qe.execSelect() ;
             ResultSetFormatter.out(rs) ;
-        } finally { qe.close() ; }
+        }
         // Does not close the JDBC connection.
         // Do not call : store.getConnection().close() , which does close the underlying connection.
         store.close() ;
diff --git a/jena-tdb/src-examples/tdb/examples/ExQuadFilter.java b/jena-tdb/src-examples/tdb/examples/ExQuadFilter.java
index 20782e3..95357b8 100644
--- a/jena-tdb/src-examples/tdb/examples/ExQuadFilter.java
+++ b/jena-tdb/src-examples/tdb/examples/ExQuadFilter.java
@@ -18,9 +18,9 @@
 
 package tdb.examples;
 
-import org.apache.jena.atlas.iterator.Filter ;
-import org.apache.jena.atlas.lib.Tuple ;
+import java.util.function.Predicate;
 
+import org.apache.jena.atlas.lib.tuple.Tuple;
 import org.apache.jena.graph.NodeFactory ;
 import org.apache.jena.query.* ;
 import org.apache.jena.sparql.core.DatasetGraph ;
@@ -36,7 +36,7 @@
  * Can be used to exclude data from specific graphs.   
  * This mechanism is not limited to graphs - it works for properties or anything
  * where the visibility of otherwise is determined by the elements of the quad. 
- * See <a href="http://incubator.apache.org/jena/documentation/tdb/quadfilter.html">QuadFiltering</a>
+ * See <a href="http://jena.apache.org/documentation/tdb/quadfilter.html">QuadFiltering</a>
  * for further details.
  */
 
@@ -50,7 +50,7 @@
         TDB.getContext().setTrue(TDB.symUnionDefaultGraph) ;
         
         Dataset ds = setup() ;
-        Filter<Tuple<NodeId>> filter = createFilter(ds) ;
+        Predicate<Tuple<NodeId>> filter = createFilter(ds) ;
         example(ds, filter) ;
     }
     
@@ -67,7 +67,7 @@
     }
         
     /** Create a filter to exclude the graph http://example/g2 */
-    private static Filter<Tuple<NodeId>> createFilter(Dataset ds)
+    private static Predicate<Tuple<NodeId>> createFilter(Dataset ds)
     {
         // Filtering operates at a very low level: 
         // Need to know the internal identifier for the graph name. 
@@ -77,26 +77,24 @@
         
         // Filter for accept/reject as quad as being visible.
         // Return true for "accept", false for "reject"
-        Filter<Tuple<NodeId>> filter = new Filter<Tuple<NodeId>>() {
-            @Override
-            public boolean accept(Tuple<NodeId> item)
+        Predicate<Tuple<NodeId>> filter = item ->
             {
                 // Reverse the lookup as a demo
                 //Node n = TDBInternal.getNode(target) ;
                 //System.err.println(item) ;
-                if ( item.size() == 4 && item.get(0).equals(target) )
+                if ( item.len() == 4 && item.get(0).equals(target) )
                 {
                     //System.out.println("Reject: "+item) ;
                     return false ;
                 }
                 //System.out.println("Accept: "+item) ;
                 return true ;
-            } } ;
+            } ;
             
         return filter ;
     }            
         
-    private static void example(Dataset ds, Filter<Tuple<NodeId>> filter)
+    private static void example(Dataset ds, Predicate<Tuple<NodeId>> filter)
     {
         String[] x = {
             "SELECT * { GRAPH ?g { ?s ?p ?o } }",
@@ -113,23 +111,21 @@
         
     }
 
-    private static void example(Dataset ds, String qs, Filter<Tuple<NodeId>> filter)
+    private static void example(Dataset ds, String qs, Predicate<Tuple<NodeId>> filter)
     {
         System.out.println() ;
         Query query = QueryFactory.create(qs) ;
         System.out.println(qs) ;
-        QueryExecution qExec = QueryExecutionFactory.create(query, ds) ;
-        // Install filter for this query only.
-        if ( filter != null )
-        {
-            System.out.println("Install quad-level filter") ;
-            qExec.getContext().set(SystemTDB.symTupleFilter, filter) ;
+        try ( QueryExecution qExec = QueryExecutionFactory.create(query, ds) ) {
+            // Install filter for this query only.
+            if ( filter != null )
+            {
+                System.out.println("Install quad-level filter") ;
+                qExec.getContext().set(SystemTDB.symTupleFilter, filter) ;
+            }
+            else
+                System.out.println("No quad-level filter") ;
+            ResultSetFormatter.out(qExec.execSelect()) ;
         }
-        else
-            System.out.println("No quad-level filter") ;
-        ResultSetFormatter.out(qExec.execSelect()) ;
-        qExec.close() ;
-
     }
-        
 }
diff --git a/jena-tdb/src-examples/tdb/examples/ExTDB4.java b/jena-tdb/src-examples/tdb/examples/ExTDB4.java
index bb9ea1a..af7dfd3 100644
--- a/jena-tdb/src-examples/tdb/examples/ExTDB4.java
+++ b/jena-tdb/src-examples/tdb/examples/ExTDB4.java
@@ -50,11 +50,9 @@
         // See http://incubator.apache.org/jena/documentation/query/app_api.html
         
         Query query = QueryFactory.create(sparqlQueryString) ;
-        QueryExecution qexec = QueryExecutionFactory.create(query, dataset) ;
-        ResultSet results = qexec.execSelect() ;
-        ResultSetFormatter.out(results) ;
-        qexec.close() ;
-
-        dataset.close();
+        try ( QueryExecution qexec = QueryExecutionFactory.create(query, dataset) ) {
+            ResultSet results = qexec.execSelect() ;
+            ResultSetFormatter.out(results) ;
+        }
     }
 }
diff --git a/jena-tdb/src-examples/tdb/examples/ExTDB5.java b/jena-tdb/src-examples/tdb/examples/ExTDB5.java
index 92517d5..2b8df5c 100644
--- a/jena-tdb/src-examples/tdb/examples/ExTDB5.java
+++ b/jena-tdb/src-examples/tdb/examples/ExTDB5.java
@@ -18,53 +18,41 @@
 
 package tdb.examples;
 
-import org.apache.jena.query.Dataset ;
-import org.apache.jena.query.Query ;
-import org.apache.jena.query.QueryExecution ;
-import org.apache.jena.query.QueryExecutionFactory ;
-import org.apache.jena.query.QueryFactory ;
-import org.apache.jena.query.QuerySolution ;
-import org.apache.jena.query.ResultSet ;
-import org.apache.jena.tdb.TDBFactory ;
+import org.apache.jena.query.Dataset;
+import org.apache.jena.query.Query;
+import org.apache.jena.query.QueryExecution;
+import org.apache.jena.query.QueryExecutionFactory;
+import org.apache.jena.query.QueryFactory;
+import org.apache.jena.query.QuerySolution;
+import org.apache.jena.query.ResultSet;
+import org.apache.jena.tdb.TDBFactory;
 
-/** Example of creating a TDB-backed model.
- *  The preferred way is to create a dataset then get the mode required from the dataset.
- *  The dataset can be used for SPARQL query and update
- *  but the Model (or Graph) can also be used.
- *  
- *  All the Jena APIs work on the model.
- *   
- *  Calling TDBFactory is the only place TDB-specific code is needed.
- *  
- *  See also ExTDB_Txn1 for use with transactions.
+/**
+ * Example of creating a TDB-backed model. The preferred way is to create a dataset
+ * then get the mode required from the dataset. The dataset can be used for SPARQL
+ * query and update but the Model (or Graph) can also be used. All the Jena APIs work
+ * on the model. Calling TDBFactory is the only place TDB-specific code is needed.
+ * See also ExTDB_Txn1 for use with transactions.
  */
 
-public class ExTDB5
-{
-    public static void main(String... argv)
-    {
+public class ExTDB5 {
+    public static void main(String...argv) {
         // Direct way: Make a TDB-back Jena model in the named directory.
-        String directory = "MyDatabases/DB1" ;
-        Dataset dataset = TDBFactory.createDataset(directory) ;
-        
-        // Potentially expensive query.
-        String sparqlQueryString = "SELECT (count(*) AS ?count) { ?s ?p ?o }" ;
-        // See http://incubator.apache.org/jena/documentation/query/app_api.html
-        
-        Query query = QueryFactory.create(sparqlQueryString) ;
-        QueryExecution qexec = QueryExecutionFactory.create(query, dataset) ;
-        try {
-          ResultSet results = qexec.execSelect() ;
-          for ( ; results.hasNext() ; )
-          {
-              QuerySolution soln = results.nextSolution() ;
-              int count = soln.getLiteral("count").getInt() ;
-              System.out.println("count = "+count) ;
-          }
-        } finally { qexec.close() ; }
+        String directory = "MyDatabases/DB1";
+        Dataset dataset = TDBFactory.createDataset(directory);
 
-        // Close the dataset.
-        dataset.close();
-        
+        // Potentially expensive query.
+        String sparqlQueryString = "SELECT (count(*) AS ?count) { ?s ?p ?o }";
+        // See http://incubator.apache.org/jena/documentation/query/app_api.html
+
+        Query query = QueryFactory.create(sparqlQueryString);
+        try (QueryExecution qexec = QueryExecutionFactory.create(query, dataset)) {
+            ResultSet results = qexec.execSelect();
+            for ( ; results.hasNext() ; ) {
+                QuerySolution soln = results.nextSolution();
+                int count = soln.getLiteral("count").getInt();
+                System.out.println("count = " + count);
+            }
+        }
     }
 }
diff --git a/jena-tdb/src-examples/tdb/examples/ExTDB6.java b/jena-tdb/src-examples/tdb/examples/ExTDB6.java
index 3dd2c0a..868dc8d 100644
--- a/jena-tdb/src-examples/tdb/examples/ExTDB6.java
+++ b/jena-tdb/src-examples/tdb/examples/ExTDB6.java
@@ -36,7 +36,7 @@
 /** Example of single threaded use of TDB working with the Jena RDF API */
 public class ExTDB6
 {
-    /// observe the non-http "protocol", because it is a bad precident
+    /// observe the non-http "protocol", because it is a bad precedent
     /// to only use http IRI when there is no http protocol involved
     public static final String MY_NS =
         "x-ns://example.org/ns1/";
@@ -45,7 +45,7 @@
         /// turn off the "No BGP optimizer warning"
         TDB.setOptimizerWarningFlag(false);
 
-        final IRIFactory iriFactory = IRIFactory.semanticWebImplementation();
+        final IRIFactory iriFactory = IRIFactory.iriImplementation();
 
         final String DATASET_DIR_NAME = "data0";
         final Dataset data0 = TDBFactory.createDataset( DATASET_DIR_NAME );
@@ -102,15 +102,14 @@
             out.println("QueryFactory.TIME="+(t1 - t0));
 
             t0 = System.currentTimeMillis();
-            final QueryExecution qExec = QueryExecutionFactory
+            try ( QueryExecution qExec = QueryExecutionFactory
                     // if you query the whole DataSet,
                     // you have to provide a FROM in the SparQL
                     //.create(q, data0);
-                    .create(q, model);
-            t1 = System.currentTimeMillis();
-            out.println("QueryExecutionFactory.TIME="+(t1 - t0));
+                    .create(q, model) ) {
+                t1 = System.currentTimeMillis();
+                out.println("QueryExecutionFactory.TIME="+(t1 - t0));
 
-            try {
                 t0 = System.currentTimeMillis();
                 ResultSet rs = qExec.execSelect();
                 t1 = System.currentTimeMillis();
@@ -123,8 +122,6 @@
                         out.println("\t"+name+" := "+sol.get(name));
                     }
                 }
-            } finally {
-                qExec.close();
             }
         }
         out.println("closing graph");
diff --git a/jena-tdb/src-examples/tdb/examples/ExTDB_Txn1.java b/jena-tdb/src-examples/tdb/examples/ExTDB_Txn1.java
index 57629a4..4c4a2fa 100644
--- a/jena-tdb/src-examples/tdb/examples/ExTDB_Txn1.java
+++ b/jena-tdb/src-examples/tdb/examples/ExTDB_Txn1.java
@@ -18,23 +18,20 @@
 
 package tdb.examples;
 
-import org.apache.jena.query.Dataset ;
-import org.apache.jena.query.Query ;
-import org.apache.jena.query.QueryExecution ;
-import org.apache.jena.query.QueryExecutionFactory ;
-import org.apache.jena.query.QueryFactory ;
-import org.apache.jena.query.QuerySolution ;
-import org.apache.jena.query.ReadWrite ;
-import org.apache.jena.query.ResultSet ;
+import org.apache.jena.query.*;
+import org.apache.jena.system.Txn;
 import org.apache.jena.tdb.TDBFactory ;
 
-/** Example of a READ transaction. */
+/**
+ * Example of a READ transaction.
+ * See {@link Txn#executeRead}.
+ */
 public class ExTDB_Txn1
 {
     public static void main(String... argv)
     {
-        String directory = "MyDatabases/DB1" ;
-        Dataset dataset = TDBFactory.createDataset(directory) ;
+        String directory = "MyDatabases/DB1";
+        Dataset dataset = TDBFactory.createDataset(directory);
 
         // Start READ transaction. 
         //   No updates or changes to the dataset are possible while this
@@ -42,41 +39,36 @@
         //   An application can have other Datasets, in the same JVM, 
         //   tied to the same TDB database performing read or write
         //   transactions concurrently.
+
+        // A READ transaction is
+        // dataset.begin(ReadWrite.READ);
+        // try {
+        // ...
+        // ... The app can also call dataset.abort() or dataset.commit() here; commit is not necessary
+        // } finally { dataset.end();}
         
-        dataset.begin(ReadWrite.READ) ;
-        try
-        {
+        // Use Txn.executeRead when the app knows there are no updates.
+        // Can use Txn.execute when a write is possible.
+        Txn.executeRead(dataset, ()-> {
             // Do some queries
-            String sparqlQueryString1 = "SELECT (count(*) AS ?count) { ?s ?p ?o }" ;
-            execQuery(sparqlQueryString1, dataset) ;
-            
-            String sparqlQueryString2 = "SELECT * { ?s ?p ?o }" ;
-            execQuery(sparqlQueryString2, dataset) ;
-            
-            // Can also call dataset.abort() or dataset.commit() here 
-        } finally
-        {
-            // Notify the end of the READ transaction.
-            // Any use of dataset.abort() or dataset.commit() or dataset.end()
-            // .end() can be called multiple times for the same .begin(READ)
-            dataset.end() ;
-        }
+            String sparqlQueryString1 = "SELECT (count(*) AS ?count) { ?s ?p ?o }";
+            execQuery(sparqlQueryString1, dataset);
+
+            String sparqlQueryString2 = "SELECT * { ?s ?p ?o }";
+            execQuery(sparqlQueryString2, dataset);
+        });
     }
     
     public static void execQuery(String sparqlQueryString, Dataset dataset)
     {
-        Query query = QueryFactory.create(sparqlQueryString) ;
-        QueryExecution qexec = QueryExecutionFactory.create(query, dataset) ;
-        try {
-            ResultSet results = qexec.execSelect() ;
-            for ( ; results.hasNext() ; )
-            {
-                QuerySolution soln = results.nextSolution() ;
-                int count = soln.getLiteral("count").getInt() ;
-                System.out.println("count = "+count) ;
+        Query query = QueryFactory.create(sparqlQueryString);
+        try ( QueryExecution qexec = QueryExecutionFactory.create(query, dataset) ) {
+            ResultSet results = qexec.execSelect();
+            for ( ; results.hasNext() ; ) {
+                QuerySolution soln = results.nextSolution();
+                int count = soln.getLiteral("count").getInt();
+                System.out.println("count = " + count);
             }
-          } finally { qexec.close() ; }
+        }
     }
-    
 }
-
diff --git a/jena-tdb/src-examples/tdb/examples/ExTDB_Txn2.java b/jena-tdb/src-examples/tdb/examples/ExTDB_Txn2.java
index a13293d..3b74518 100644
--- a/jena-tdb/src-examples/tdb/examples/ExTDB_Txn2.java
+++ b/jena-tdb/src-examples/tdb/examples/ExTDB_Txn2.java
@@ -18,66 +18,56 @@
 
 package tdb.examples;
 
-import org.apache.jena.atlas.lib.StrUtils ;
+import org.apache.jena.atlas.lib.StrUtils;
+import org.apache.jena.query.Dataset;
+import org.apache.jena.system.Txn;
+import org.apache.jena.tdb.TDBFactory;
+import org.apache.jena.update.UpdateExecutionFactory;
+import org.apache.jena.update.UpdateFactory;
+import org.apache.jena.update.UpdateProcessor;
+import org.apache.jena.update.UpdateRequest;
 
-import org.apache.jena.query.Dataset ;
-import org.apache.jena.query.ReadWrite ;
-import org.apache.jena.tdb.TDBFactory ;
-import org.apache.jena.update.GraphStore ;
-import org.apache.jena.update.GraphStoreFactory ;
-import org.apache.jena.update.UpdateExecutionFactory ;
-import org.apache.jena.update.UpdateFactory ;
-import org.apache.jena.update.UpdateProcessor ;
-import org.apache.jena.update.UpdateRequest ;
+/**
+ * Example of a WRITE transaction. 
+ * See {@link Txn#executeRead}.
+ */
+public class ExTDB_Txn2 {
+    public static void main(String...argv) {
+        String directory = "MyDatabases/DB1";
+        Dataset dataset = TDBFactory.createDataset(directory);
 
-/** Example of a WRITE transaction. */
-public class ExTDB_Txn2
-{
-    public static void main(String... argv)
-    {
-        String directory = "MyDatabases/DB1" ;
-        Dataset dataset = TDBFactory.createDataset(directory) ;
+        // Start WRITE transaction.
+        // It's possible to read from the dataset inside the write transaction.
 
-        // Start WRITE transaction. 
-        //   It's possible to read from the datet inside the write transaction.
-
-        //   An application can have other Datasets, in the same JVM, 
-        //   tied to the same TDB database performing read
-        //   transactions concurrently. If another write transaction
-        //   starts, the call of dataset.begin(WRITE) blocks until
-        //   existing writer finishes.
+        // An application can have other Datasets, in the same JVM,
+        // tied to the same TDB database performing read
+        // transactions concurrently. If another write transaction
+        // starts, the call of dataset.begin(WRITE) blocks until
+        // existing writer finishes.
         
-        dataset.begin(ReadWrite.WRITE) ;
-        try
-        {
-            GraphStore graphStore = GraphStoreFactory.create(dataset) ;
+        // A WRITE transaction is
+        // dataset.begin(ReadWrite.READ);
+        // try {
+        // ...
+        // ... dataset.abort() or dataset.commit()
+        // } finally { dataset.end();}
+        //
+
+        Txn.executeWrite(dataset, ()->{
             // Do a SPARQL Update.
-            String sparqlUpdateString = StrUtils.strjoinNL(
-                 "PREFIX . <http://example/>",
-                 "INSERT { :s :p ?now } WHERE { BIND(now() AS ?now) }"
-                 ) ;
+            String sparqlUpdateString = StrUtils.strjoinNL
+                ("PREFIX . <http://example/>"
+                ,"INSERT { :s :p ?now } WHERE { BIND(now() AS ?now) }"
+                );
 
-            execUpdate(sparqlUpdateString, graphStore) ;
-            dataset.commit() ;
-            // Or call .abort()
-            
-        } finally
-        {
-            // Notify the end of the transaction.
-            // The transaction was finished at the point .commit or .abort was called.
-            // .end will force an abort() if no previous call to .commit() or .abort()
-            // has occurred, so .end() help manage track the state of the transaction.
-            // .end() can be called multiple times for the same .begin(WRITE)
-            dataset.end() ;
-        }
+            execUpdate(sparqlUpdateString, dataset);
+        });
     }
-    
-    public static void execUpdate(String sparqlUpdateString, GraphStore graphStore)
-    {
-        UpdateRequest request = UpdateFactory.create(sparqlUpdateString) ;
-        UpdateProcessor proc = UpdateExecutionFactory.create(request, graphStore) ;
-        proc.execute() ;
+
+    public static void execUpdate(String sparqlUpdateString, Dataset dataset) {
+        UpdateRequest request = UpdateFactory.create(sparqlUpdateString);
+        UpdateProcessor proc = UpdateExecutionFactory.create(request, dataset);
+        proc.execute();
     }
-    
+
 }
-
diff --git a/jena-tdb/src-examples/tdb/examples/ExTDB_Txn3.java b/jena-tdb/src-examples/tdb/examples/ExTDB_Txn3.java
index 1b6f067..93f377b 100644
--- a/jena-tdb/src-examples/tdb/examples/ExTDB_Txn3.java
+++ b/jena-tdb/src-examples/tdb/examples/ExTDB_Txn3.java
@@ -18,10 +18,10 @@
 
 package tdb.examples;
 
-import org.apache.jena.query.* ;
-import org.apache.jena.sparql.core.DatasetGraph ;
-import org.apache.jena.tdb.TDBFactory ;
-import org.apache.jena.tdb.transaction.DatasetGraphTransaction ;
+import org.apache.jena.query.*;
+import org.apache.jena.sparql.core.DatasetGraph;
+import org.apache.jena.system.Txn;
+import org.apache.jena.tdb.TDBFactory;
 
 /** Illustration of working at the DatasetGraph level.
  *  Normally, applications work with {@link Dataset}.
@@ -32,40 +32,31 @@
 {
     public static void main(String... argv)
     {
-        DatasetGraphTransaction dsg = (DatasetGraphTransaction)TDBFactory.createDatasetGraph() ;
+        DatasetGraph dsg = TDBFactory.createDatasetGraph();
 
-        // Start READ transaction. 
-        dsg.begin(ReadWrite.READ) ;
-        
-        try
-        {
+        // Start a transaction. It starts in "read" mode and promotes to "write" mode if necessary. 
+        Txn.execute(dsg, ()->{
             // Do some queries
-            String sparqlQueryString1 = "SELECT (count(*) AS ?count) { ?s ?p ?o }" ;
-            execQuery(sparqlQueryString1, dsg) ;
-        } finally
-        {
-            dsg.end() ;
-        }
+            String sparqlQueryString1 = "SELECT (count(*) AS ?count) { ?s ?p ?o }";
+            execQuery(sparqlQueryString1, dsg);
+        });
     }
     
     public static void execQuery(String sparqlQueryString, DatasetGraph dsg)
     {
-        // Add a datset wrapper to conform with the query interface.
+        // Add a dataset wrapper to conform with the query interface.
         // This should not be very expensive.
-        Dataset dataset = DatasetFactory.create(dsg) ;
+        Dataset dataset = DatasetFactory.wrap(dsg);
         
-        Query query = QueryFactory.create(sparqlQueryString) ;
-        QueryExecution qexec = QueryExecutionFactory.create(query, dataset) ;
-        try {
-            ResultSet results = qexec.execSelect() ;
-            for ( ; results.hasNext() ; )
+        Query query = QueryFactory.create(sparqlQueryString);
+        try ( QueryExecution qexec = QueryExecutionFactory.create(query, dataset) ) {
+            ResultSet results = qexec.execSelect();
+            for (; results.hasNext(); )
             {
-                QuerySolution soln = results.nextSolution() ;
-                int count = soln.getLiteral("count").getInt() ;
-                System.out.println("count = "+count) ;
+                QuerySolution soln = results.nextSolution();
+                int count = soln.getLiteral("count").getInt();
+                System.out.println("count = "+count);
             }
-          } finally { qexec.close() ; }
+        }
     }
-    
 }
-