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 2016/09/27 20:11:43 UTC
[1/6] jena git commit: JENA-1237: Capture transaction snapshot during
begin.
Repository: jena
Updated Branches:
refs/heads/master 0a60d3804 -> fbb53efcc
JENA-1237: Capture transaction snapshot during begin.
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/cc2c4bd5
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/cc2c4bd5
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/cc2c4bd5
Branch: refs/heads/master
Commit: cc2c4bd54c15b958dede6b4e83e6ee440a3157c8
Parents: 0a60d38
Author: Andy Seaborne <an...@apache.org>
Authored: Sat Sep 17 16:51:25 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sat Sep 17 16:51:25 2016 +0100
----------------------------------------------------------------------
.../java/org/apache/jena/sparql/core/mem/PMapTupleTable.java | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/cc2c4bd5/jena-arq/src/main/java/org/apache/jena/sparql/core/mem/PMapTupleTable.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/mem/PMapTupleTable.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/mem/PMapTupleTable.java
index 3231f2d..c1cda88 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/mem/PMapTupleTable.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/mem/PMapTupleTable.java
@@ -55,7 +55,7 @@ public abstract class PMapTupleTable<TupleMapType, TupleType, ConsumerType>
return master;
}
- private final ThreadLocal<TupleMapType> local = withInitial(() -> master().get());
+ private final ThreadLocal<TupleMapType> local = withInitial(()->null);
/**
* @return a thread-local transactional reference to the internal table structure
@@ -88,7 +88,9 @@ public abstract class PMapTupleTable<TupleMapType, TupleType, ConsumerType>
* {@link #local} is initialized via {@link #initial()}
*/
@Override
- public void begin(final ReadWrite rw) {}
+ public void begin(final ReadWrite rw) {
+ local.set(master().get());
+ }
@Override
public void end() {
[5/6] jena git commit: JENA-1223: Incorporate review suggestions
Posted by an...@apache.org.
JENA-1223: Incorporate review suggestions
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/779e85cf
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/779e85cf
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/779e85cf
Branch: refs/heads/master
Commit: 779e85cf4d66a0dcbfea41a657f262249c2d9f57
Parents: 2610908
Author: Andy Seaborne <an...@apache.org>
Authored: Tue Sep 27 18:51:17 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Tue Sep 27 18:51:17 2016 +0100
----------------------------------------------------------------------
.../sparql/core/mem/TestDatasetGraphInMemoryPromote.java | 2 +-
.../jena/sparql/transaction/AbstractTestTransPromote.java | 5 +++--
.../sparql/transaction/AbstractTestTransactionIsolation.java | 8 ++------
.../org/apache/jena/tdb/transaction/TestTransPromoteTDB.java | 2 +-
4 files changed, 7 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/779e85cf/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryPromote.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryPromote.java b/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryPromote.java
index dbcfde0..644de58 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryPromote.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryPromote.java
@@ -59,7 +59,7 @@ public class TestDatasetGraphInMemoryPromote extends AbstractTestTransPromote {
}
@Override
- protected Class<?> getTransactionExceptionClass() {
+ protected Class<JenaTransactionException> getTransactionExceptionClass() {
return JenaTransactionException.class ;
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/jena/blob/779e85cf/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 f7c7fcb..aec1b8f 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
@@ -81,7 +81,7 @@ public abstract class AbstractTestTransPromote {
// The exact class used by exceptions of the system under test.
// TDB transctions are in the TDBException hierarchy
// so can't be JenaTransactionException.
- protected abstract Class<?> getTransactionExceptionClass() ;
+ protected abstract Class<? extends Exception> getTransactionExceptionClass() ;
@Before
public void before() {
@@ -287,7 +287,8 @@ public abstract class AbstractTestTransPromote {
getTransactionExceptionClass()) ;
}
- private void expect(Runnable runnable, Class<?>...classes) {
+ @SafeVarargs
+ private final void expect(Runnable runnable, Class<? extends Exception>...classes) {
try {
runnable.run();
fail("Exception expected") ;
http://git-wip-us.apache.org/repos/asf/jena/blob/779e85cf/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransactionIsolation.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransactionIsolation.java b/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransactionIsolation.java
index 85a574f..f4d85cd 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransactionIsolation.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransactionIsolation.java
@@ -18,9 +18,8 @@
package org.apache.jena.sparql.transaction;
-import static org.apache.jena.query.ReadWrite.* ;
+import static org.apache.jena.query.ReadWrite.WRITE ;
-import org.apache.jena.atlas.iterator.Iter ;
import org.apache.jena.sparql.core.DatasetGraph ;
import org.apache.jena.sparql.core.Quad ;
import org.apache.jena.sparql.sse.SSE ;
@@ -42,10 +41,7 @@ public abstract class AbstractTestTransactionIsolation {
// returns but the action of the ThreadTxn is not triggered
// until other.run() is called.
DatasetGraph dsg = create() ;
- ThreadAction other = ThreadTxn.threadTxnRead(dsg, ()-> {
- long x = Iter.count(dsg.find()) ;
- Assert.assertEquals(0, x) ;
- }) ;
+ ThreadAction other = ThreadTxn.threadTxnRead(dsg, ()-> Assert.assertTrue(dsg.isEmpty()) ) ;
dsg.begin(WRITE) ;
dsg.add(q1) ;
dsg.commit() ;
http://git-wip-us.apache.org/repos/asf/jena/blob/779e85cf/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromoteTDB.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromoteTDB.java b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromoteTDB.java
index 61ba5f1..c93ecb1 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromoteTDB.java
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromoteTDB.java
@@ -66,7 +66,7 @@ public class TestTransPromoteTDB extends AbstractTestTransPromote {
}
@Override
- protected Class<?> getTransactionExceptionClass() {
+ protected Class<TDBTransactionException> getTransactionExceptionClass() {
return TDBTransactionException.class ;
}
}
\ No newline at end of file
[2/6] jena git commit: Clean up.
Posted by an...@apache.org.
Clean up.
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/f9f2870e
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/f9f2870e
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/f9f2870e
Branch: refs/heads/master
Commit: f9f2870e29fd1ac51c49740a42f6fbb644b7616d
Parents: cc2c4bd
Author: Andy Seaborne <an...@apache.org>
Authored: Sat Sep 17 17:02:50 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sat Sep 17 17:02:50 2016 +0100
----------------------------------------------------------------------
.../tdb/store/nodetable/NodeTableReadonly.java | 6 +--
.../tdb/store/nodetable/NodeTableWrapper.java | 44 ++++++++++----------
2 files changed, 24 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/f9f2870e/jena-tdb/src/main/java/org/apache/jena/tdb/store/nodetable/NodeTableReadonly.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/store/nodetable/NodeTableReadonly.java b/jena-tdb/src/main/java/org/apache/jena/tdb/store/nodetable/NodeTableReadonly.java
index 963c341..c09140f 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/store/nodetable/NodeTableReadonly.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/store/nodetable/NodeTableReadonly.java
@@ -24,14 +24,12 @@ import org.apache.jena.tdb.store.NodeId ;
public class NodeTableReadonly extends NodeTableWrapper
{
- public NodeTableReadonly(NodeTable nodeTable)
- {
+ public NodeTableReadonly(NodeTable nodeTable) {
super(nodeTable) ;
}
@Override
- public NodeId getAllocateNodeId(Node node)
- {
+ public NodeId getAllocateNodeId(Node node) {
NodeId nodeId = getNodeIdForNode(node) ;
if ( NodeId.isDoesNotExist(nodeId) )
throw new TDBException("Allocation attempt on NodeTableReadonly") ;
http://git-wip-us.apache.org/repos/asf/jena/blob/f9f2870e/jena-tdb/src/main/java/org/apache/jena/tdb/store/nodetable/NodeTableWrapper.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/store/nodetable/NodeTableWrapper.java b/jena-tdb/src/main/java/org/apache/jena/tdb/store/nodetable/NodeTableWrapper.java
index 57b5182..c2378b0 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/store/nodetable/NodeTableWrapper.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/store/nodetable/NodeTableWrapper.java
@@ -30,30 +30,26 @@ public class NodeTableWrapper implements NodeTable
protected final NodeTable nodeTable ;
@Override
public final NodeTable wrapped() { return nodeTable ; }
-
- protected NodeTableWrapper(NodeTable nodeTable)
- {
+
+ protected NodeTableWrapper(NodeTable nodeTable) {
this.nodeTable = nodeTable ;
}
-
+
@Override
- public NodeId getAllocateNodeId(Node node)
- {
+ public NodeId getAllocateNodeId(Node node) {
return nodeTable.getAllocateNodeId(node) ;
}
@Override
- public NodeId getNodeIdForNode(Node node)
- {
+ public NodeId getNodeIdForNode(Node node) {
return nodeTable.getNodeIdForNode(node) ;
}
@Override
- public Node getNodeForNodeId(NodeId id)
- {
+ public Node getNodeForNodeId(NodeId id) {
return nodeTable.getNodeForNodeId(id) ;
}
-
+
@Override
public boolean containsNode(Node node) {
return nodeTable.containsNode(node) ;
@@ -61,27 +57,31 @@ public class NodeTableWrapper implements NodeTable
@Override
public boolean containsNodeId(NodeId nodeId) {
- return nodeTable.containsNodeId(nodeId) ; }
+ return nodeTable.containsNodeId(nodeId) ;
+ }
@Override
- public NodeId allocOffset()
- {
+ public NodeId allocOffset() {
return nodeTable.allocOffset() ;
}
@Override
- public Iterator<Pair<NodeId, Node>> all()
- {
- return nodeTable.all();
+ public Iterator<Pair<NodeId, Node>> all() {
+ return nodeTable.all() ;
}
@Override
- public boolean isEmpty() { return nodeTable.isEmpty() ; }
-
+ public boolean isEmpty() {
+ return nodeTable.isEmpty() ;
+ }
+
@Override
- public void sync() { nodeTable.sync() ; }
+ public void sync() {
+ nodeTable.sync() ;
+ }
@Override
- public void close()
- { nodeTable.close() ; }
+ public void close() {
+ nodeTable.close() ;
+ }
}
[6/6] jena git commit: JENA-1223: Merge commit 'refs/pull/170/head'
of github.com:apache/jena
Posted by an...@apache.org.
JENA-1223: Merge commit 'refs/pull/170/head' of github.com:apache/jena
This closes #170.
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/fbb53efc
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/fbb53efc
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/fbb53efc
Branch: refs/heads/master
Commit: fbb53efccb59cf6596e7c4601653d8eb0470f36d
Parents: 0a60d38 779e85c
Author: Andy Seaborne <an...@apache.org>
Authored: Tue Sep 27 21:10:51 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Tue Sep 27 21:10:51 2016 +0100
----------------------------------------------------------------------
.../sparql/core/mem/DatasetGraphInMemory.java | 60 ++-
.../jena/sparql/core/mem/PMapTupleTable.java | 6 +-
.../jena/sparql/core/mem/TS_DatasetTxnMem.java | 4 +-
.../mem/TestDatasetGraphInMemoryIsolation.java | 30 ++
.../mem/TestDatasetGraphInMemoryPromote.java | 65 +++
.../transaction/AbstractTestTransPromote.java | 423 +++++++++++++++++++
.../AbstractTestTransactionIsolation.java | 51 +++
.../AbstractTestTransactionLifecycle.java | 2 -
.../tdb/store/nodetable/NodeTableReadonly.java | 6 +-
.../tdb/store/nodetable/NodeTableWrapper.java | 44 +-
.../tdb/transaction/TransactionManager.java | 2 +-
.../jena/tdb/transaction/TS_TransactionTDB.java | 3 +-
.../tdb/transaction/TestTransIsolation.java | 32 ++
.../jena/tdb/transaction/TestTransPromote.java | 394 -----------------
.../tdb/transaction/TestTransPromoteTDB.java | 72 ++++
15 files changed, 762 insertions(+), 432 deletions(-)
----------------------------------------------------------------------
[4/6] jena git commit: JENA-1223: Transaction promotion for TIM
Posted by an...@apache.org.
JENA-1223: Transaction promotion for TIM
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/26109087
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/26109087
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/26109087
Branch: refs/heads/master
Commit: 2610908744464e1247b2896f7b26e78cadf56d84
Parents: 51175d2
Author: Andy Seaborne <an...@apache.org>
Authored: Tue Sep 20 19:24:27 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Tue Sep 20 19:24:27 2016 +0100
----------------------------------------------------------------------
.../sparql/core/mem/DatasetGraphInMemory.java | 60 ++-
.../jena/sparql/core/mem/TS_DatasetTxnMem.java | 3 +-
.../mem/TestDatasetGraphInMemoryPromote.java | 65 +++
.../transaction/AbstractTestTransPromote.java | 422 +++++++++++++++++++
.../jena/tdb/transaction/TS_TransactionTDB.java | 2 +-
.../jena/tdb/transaction/TestTransPromote.java | 391 -----------------
.../tdb/transaction/TestTransPromoteTDB.java | 72 ++++
7 files changed, 617 insertions(+), 398 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/26109087/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 8af0734..d6dfdff 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
@@ -27,10 +27,12 @@ import static org.apache.jena.sparql.util.graph.GraphUtils.triples2quadsDftGraph
import static org.slf4j.LoggerFactory.getLogger;
import java.util.Iterator;
+import java.util.concurrent.atomic.AtomicLong ;
import java.util.concurrent.locks.ReentrantLock ;
import java.util.function.Consumer;
import java.util.function.Supplier;
+import org.apache.jena.atlas.lib.InternalErrorException ;
import org.apache.jena.graph.Graph;
import org.apache.jena.graph.Node;
import org.apache.jena.graph.Triple;
@@ -42,9 +44,8 @@ import org.apache.jena.sparql.core.* ;
import org.slf4j.Logger;
/**
- * A {@link DatasetGraph} backed by an {@link QuadTable}. By default, this is a {@link HexTable} designed for high-speed
- * in-memory operation.
- *
+ * A {@link DatasetGraph} backed by an {@link QuadTable}. By default, this is a
+ * {@link HexTable} designed for high-speed in-memory operation.
*/
public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Transactional {
@@ -63,6 +64,13 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
* insures that they are made consistently.
*/
private final ReentrantLock systemLock = new ReentrantLock(true);
+
+ /**
+ * Dataset version.
+ * A write transaction increments this in commit.
+ */
+ private final AtomicLong generation = new AtomicLong(0) ;
+ private final ThreadLocal<Long> version = withInitial(() -> 0L);
private final ThreadLocal<Boolean> isInTransaction = withInitial(() -> false);
@@ -133,6 +141,7 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
withLock(systemLock, () ->{
quadsIndex().begin(readWrite);
defaultGraph().begin(readWrite);
+ version.set(generation.get());
}) ;
}
@@ -147,6 +156,7 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
private void finishTransaction() {
isInTransaction.remove();
transactionType.remove();
+ version.remove();
transactionLock.leaveCriticalSection();
}
@@ -165,6 +175,12 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
defaultGraph().commit();
quadsIndex().end();
defaultGraph().end();
+
+ if ( transactionType().equals(WRITE) ) {
+ if ( version.get() != generation.get() )
+ throw new InternalErrorException(String.format("Version=%d, Generation=%d",version.get(),generation.get())) ;
+ generation.incrementAndGet() ;
+ }
} ) ;
}
@@ -306,8 +322,42 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
} finally {
end();
}
- } else if (transactionType().equals(WRITE)) mutator.accept(payload);
- else throw new JenaTransactionException("Tried to write inside a READ transaction!");
+ return ;
+ }
+ if ( !transactionType().equals(WRITE) ) {
+ if ( ! promotion )
+ throw new JenaTransactionException("Tried to write inside a READ transaction!");
+ promote(readCommittedPromotion) ;
+ }
+ mutator.accept(payload);
+ }
+
+ /*private*/public/*for development*/ static boolean promotion = false ;
+ /*private*/public/*for development*/ static boolean readCommittedPromotion = true ;
+
+ private void promote(boolean readCommited) {
+ //System.err.printf("Promote: version=%d generation=%d\n", version.get() , generation.get()) ;
+
+ // Outside lock.
+ if ( ! readCommited && version.get() != generation.get() ) {
+ // This tests for any commited writers since this transaction started.
+ // This does not catch the case of a currently active writer
+ // that has not gone to commit or abort yet.
+ // The final test is after we obtain the transactionLock.
+ throw new JenaTransactionException("Dataset changed - can't promote") ;
+ }
+
+ // Blocking on other writers.
+ transactionLock.enterCriticalSection(false);
+ // Check again now we are inside the lock.
+ if ( ! readCommited && version.get() != generation.get() ) {
+ // Can't promote - release the lock.
+ transactionLock.leaveCriticalSection();
+ throw new JenaTransactionException("Concurrent writer changed the dataset : can't promote") ;
+ }
+ // We have the lock and we have promoted!
+ transactionType(WRITE);
+ _begin(WRITE) ;
}
/**
http://git-wip-us.apache.org/repos/asf/jena/blob/26109087/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TS_DatasetTxnMem.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TS_DatasetTxnMem.java b/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TS_DatasetTxnMem.java
index f3d795b..2fa0f60 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TS_DatasetTxnMem.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TS_DatasetTxnMem.java
@@ -40,6 +40,7 @@ import org.junit.runners.Suite.SuiteClasses;
TestDatasetGraphInMemoryFind.class,
TestDatasetGraphInMemoryFindPattern.class,
- TestDatasetGraphInMemoryIsolation.class
+ TestDatasetGraphInMemoryIsolation.class,
+ TestDatasetGraphInMemoryPromote.class
})
public class TS_DatasetTxnMem {}
http://git-wip-us.apache.org/repos/asf/jena/blob/26109087/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryPromote.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryPromote.java b/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryPromote.java
new file mode 100644
index 0000000..dbcfde0
--- /dev/null
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryPromote.java
@@ -0,0 +1,65 @@
+/*
+ * 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.sparql.core.mem ;
+
+import org.apache.jena.sparql.JenaTransactionException ;
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.transaction.AbstractTestTransPromote ;
+import org.apache.log4j.Logger ;
+
+/** Tests for transactions that start read and then promote to write -- TIM */
+public class TestDatasetGraphInMemoryPromote extends AbstractTestTransPromote {
+ public TestDatasetGraphInMemoryPromote() {
+ super(getLoggers()) ;
+ }
+
+ @Override
+ protected DatasetGraph create() {
+ return new DatasetGraphInMemory() ;
+ }
+
+ private static Logger[] getLoggers() {
+ return new Logger[]{ Logger.getLogger(DatasetGraphInMemory.class) } ;
+ }
+
+ @Override
+ protected void setPromotion(boolean b) {
+ DatasetGraphInMemory.promotion = b ;
+ }
+
+ @Override
+ protected boolean getPromotion() {
+ return DatasetGraphInMemory.promotion ;
+ }
+
+ @Override
+ protected void setReadCommitted(boolean b) {
+ DatasetGraphInMemory.readCommittedPromotion = b ;
+ }
+
+ @Override
+ protected boolean getReadCommitted() {
+ return DatasetGraphInMemory.readCommittedPromotion ;
+ }
+
+ @Override
+ protected Class<?> getTransactionExceptionClass() {
+ return JenaTransactionException.class ;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/jena/blob/26109087/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
new file mode 100644
index 0000000..f7c7fcb
--- /dev/null
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransPromote.java
@@ -0,0 +1,422 @@
+/*
+ * 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.sparql.transaction ;
+
+import static org.junit.Assert.assertEquals ;
+import static org.junit.Assert.fail ;
+
+import java.util.concurrent.* ;
+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.shared.JenaException ;
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.core.Quad ;
+import org.apache.jena.sparql.sse.SSE ;
+import org.apache.jena.system.ThreadAction ;
+import org.apache.jena.system.ThreadTxn ;
+import org.apache.jena.system.Txn ;
+import org.apache.log4j.Level ;
+import org.apache.log4j.Logger ;
+import org.junit.After ;
+import org.junit.Before ;
+import org.junit.Test ;
+
+/** Tests for transactions that start read and then promote to write */
+public abstract class AbstractTestTransPromote {
+
+ // Currently,
+ // this feature is off and needs enabling via setPromotion.
+ // promotion is implicit when a write happens.
+
+ // See beforeClass / afterClass.
+
+ // Loggers.
+ private final Logger[] loggers ;
+ private Level[] levels ;
+ private boolean stdPromotion ;
+ private boolean stdReadCommitted ;
+
+ @Before
+ public void beforeLoggersNoWarnings() {
+ int N = loggers.length ;
+ levels = new Level[N] ;
+ for ( int i = 0 ; i < N ; i++ ) {
+ levels[i] = loggers[i].getLevel() ;
+ loggers[i].setLevel(Level.ERROR) ;
+ }
+ }
+
+ @After
+ public void afterResetLoggers() {
+ int N = loggers.length ;
+ for ( int i = 0 ; i < N ; i++ ) {
+ loggers[i].setLevel(levels[i]) ;
+ }
+ }
+
+ protected abstract void setPromotion(boolean b) ;
+ protected abstract boolean getPromotion() ;
+ protected abstract void setReadCommitted(boolean b) ;
+ protected abstract boolean getReadCommitted() ;
+
+ // The exact class used by exceptions of the system under test.
+ // TDB transctions are in the TDBException hierarchy
+ // so can't be JenaTransactionException.
+ protected abstract Class<?> getTransactionExceptionClass() ;
+
+ @Before
+ public void before() {
+ stdPromotion = getPromotion() ;
+ stdReadCommitted = getReadCommitted() ;
+ setPromotion(true);
+ setReadCommitted(true);
+ }
+
+ @After
+ public void after() {
+ setPromotion(stdPromotion);
+ setReadCommitted(stdReadCommitted);
+ }
+
+ protected AbstractTestTransPromote(Logger[] loggers) {
+ this.loggers = loggers ;
+ }
+
+
+ private static Quad q1 = SSE.parseQuad("(_ :s :p1 1)") ;
+ private static Quad q2 = SSE.parseQuad("(_ :s :p2 2)") ;
+ private static Quad q3 = SSE.parseQuad("(_ :s :p3 3)") ;
+
+ protected abstract DatasetGraph create() ;
+
+ protected static void assertCount(long expected, DatasetGraph dsg) {
+ dsg.begin(ReadWrite.READ) ;
+ long x = Iter.count(dsg.find()) ;
+ dsg.end() ;
+ assertEquals(expected, x) ;
+ }
+
+ // "strict" = don't see intermedioate changes.
+ // "readCommitted" = do see
+
+ // Subclass / parameterized
+
+ @Test public void promote_snapshot_01() { run_01(false) ; }
+ @Test public void promote_readCommitted_01() { run_01(true) ; }
+
+ // READ-add
+ private void run_01(boolean allowReadCommitted) {
+ setReadCommitted(allowReadCommitted);
+ DatasetGraph dsg = create() ;
+
+ dsg.begin(ReadWrite.READ) ;
+ dsg.add(q1) ;
+ dsg.commit() ;
+ dsg.end() ;
+ }
+
+ @Test public void promote_snapshot_02() { run_02(false) ; }
+ @Test public void promote_readCommitted_02() { run_02(true) ; }
+
+ // Previous transaction then READ-add
+ private void run_02(boolean allowReadCommitted) {
+ setReadCommitted(allowReadCommitted);
+ DatasetGraph dsg = create() ;
+
+ dsg.begin(ReadWrite.READ) ;dsg.end() ;
+
+ dsg.begin(ReadWrite.READ) ;
+ dsg.add(q1) ;
+ dsg.commit() ;
+ dsg.end() ;
+ }
+
+ @Test public void promote_snapshot_03() { run_03(false) ; }
+ @Test public void promote_readCommitted_03() { run_03(true) ; }
+
+ private void run_03(boolean allowReadCommitted) {
+ setReadCommitted(allowReadCommitted);
+ DatasetGraph dsg = create() ;
+
+ dsg.begin(ReadWrite.WRITE) ;dsg.commit() ; dsg.end() ;
+
+ dsg.begin(ReadWrite.READ) ;
+ dsg.add(q1) ;
+ dsg.commit() ;
+ dsg.end() ;
+ }
+
+ @Test public void promote_snapshot_04() { run_04(false) ; }
+ @Test public void promote_readCommitted_04() { run_04(true) ; }
+
+ private void run_04(boolean allowReadCommitted) {
+ setReadCommitted(allowReadCommitted);
+ DatasetGraph dsg = create() ;
+
+ dsg.begin(ReadWrite.WRITE) ;dsg.abort() ; dsg.end() ;
+
+ dsg.begin(ReadWrite.READ) ;
+ dsg.add(q1) ;
+ dsg.commit() ;
+ dsg.end() ;
+ }
+
+ @Test public void promote_snapshot_05() { run_05(false) ; }
+ @Test public void promote_readCommitted_05() { run_05(true) ; }
+
+ private void run_05(boolean allowReadCommitted) {
+ setReadCommitted(allowReadCommitted);
+ DatasetGraph dsg = create() ;
+ dsg.begin(ReadWrite.READ) ;
+ dsg.add(q1) ;
+
+ // bad - forced abort.
+ // Causes a WARN.
+ //logger1.setLevel(Level.ERROR) ;
+ dsg.end() ;
+ //logger1.setLevel(level1) ;
+
+ assertCount(0, dsg) ;
+ }
+
+ @Test public void promote_snapshot_06() { run_06(false) ; }
+ @Test public void promote_readCommitted_06() { run_06(true) ; }
+
+ // Async writer after promotion.
+ private void run_06(boolean allowReadCommitted) {
+ setReadCommitted(allowReadCommitted);
+ DatasetGraph dsg = create() ;
+ AtomicInteger a = new AtomicInteger(0) ;
+
+ Semaphore sema = new Semaphore(0) ;
+ Thread t = new Thread(() -> {
+ sema.release() ;
+ Txn.executeWrite(dsg, () -> dsg.add(q3)) ;
+ sema.release() ;
+ }) ;
+
+ dsg.begin(ReadWrite.READ) ;
+ // Promote
+ dsg.add(q1) ;
+ t.start() ;
+ // First release.
+ sema.acquireUninterruptibly() ;
+ // Thread blocked.
+ dsg.add(q2) ;
+ dsg.commit() ;
+ dsg.end() ;
+
+ // Until thread exits.
+ sema.acquireUninterruptibly() ;
+ assertCount(3, dsg) ;
+ }
+
+ @Test public void promote_snapshot_07() { run_07(false) ; }
+ @Test public void promote_readCommitted_07() { run_07(true) ; }
+
+ // Async writer after promotion.
+ private void run_07(boolean allowReadCommitted) {
+ setReadCommitted(allowReadCommitted);
+ DatasetGraph dsg = create() ;
+ // Start long running reader.
+ ThreadAction tt = ThreadTxn.threadTxnRead(dsg, () -> {
+ long x = Iter.count(dsg.find()) ;
+ if ( x != 0 )
+ throw new RuntimeException() ;
+ }) ;
+
+ // Start R->W here
+ dsg.begin(ReadWrite.READ) ;
+ dsg.add(q1) ;
+ dsg.add(q2) ;
+ dsg.commit() ;
+ dsg.end() ;
+ tt.run() ;
+ }
+
+ @Test public void promote_snapshot_08() { run_08(false) ; }
+ @Test public void promote_readCommitted_08() { run_08(true) ; }
+
+ // Async writer after promotion trasnaction ends.
+ private void run_08(boolean allowReadCommitted) {
+ setReadCommitted(allowReadCommitted);
+ DatasetGraph dsg = create() ;
+ // Start R->W here
+ dsg.begin(ReadWrite.READ) ;
+ dsg.add(q1) ;
+ dsg.add(q2) ;
+ dsg.commit() ;
+ dsg.end() ;
+ Txn.executeRead(dsg, () -> {
+ long x = Iter.count(dsg.find()) ;
+ assertEquals(2, x) ;
+ }) ;
+ }
+
+ // Tests for XXX Read-committed yes/no (false = snapshot isolation, true = read committed),
+ // and whether the other transaction commits (true) or aborts (false).
+
+ @Test
+ public void promote_10() { promote_readCommit_txnCommit(true, true) ; }
+
+ @Test
+ public void promote_11() { promote_readCommit_txnCommit(true, false) ; }
+
+ @Test
+ public void promote_12() {
+ expect(()->promote_readCommit_txnCommit(false, true) ,
+ getTransactionExceptionClass()) ;
+ }
+
+ private void expect(Runnable runnable, Class<?>...classes) {
+ try {
+ runnable.run();
+ fail("Exception expected") ;
+ } catch (Exception e) {
+ for ( Class<?> c : classes) {
+ if ( e.getClass().equals(c) )
+ return ;
+ }
+ throw e ;
+ }
+ }
+
+ @Test
+ public void promote_13() { promote_readCommit_txnCommit(false, false) ; }
+
+ private void promote_readCommit_txnCommit(boolean allowReadCommitted, boolean asyncCommit) {
+ setReadCommitted(allowReadCommitted) ;
+ DatasetGraph dsg = create() ;
+
+ ThreadAction tt = asyncCommit?
+ ThreadTxn.threadTxnWrite(dsg, () -> dsg.add(q3) ) :
+ ThreadTxn.threadTxnWriteAbort(dsg, () -> dsg.add(q3)) ;
+
+ dsg.begin(ReadWrite.READ) ;
+ // Other runs
+ tt.run() ;
+ // Can promote if readCommited
+ // Can't promote if not readCommited
+ dsg.add(q1) ;
+ if ( ! allowReadCommitted && asyncCommit )
+ fail("Should not be here") ;
+
+ assertEquals(asyncCommit, dsg.contains(q3)) ;
+ dsg.commit() ;
+ dsg.end() ;
+ //logger2.setLevel(level2);
+ }
+
+ // Active writer commits -> no promotion.
+ @Test
+ public void promote_active_writer_1() throws InterruptedException, ExecutionException {
+ expect(()->promote_active_writer(true) ,
+ getTransactionExceptionClass()) ;
+ }
+
+ // Active writer aborts -> promotion.
+ @Test
+ public void promote_active_writer_2() throws InterruptedException, ExecutionException {
+ // Active writer aborts -> promotion possible (but not implemented that way).
+ promote_active_writer(false) ;
+ }
+
+ private void promote_active_writer(boolean activeWriterCommit) {
+ ExecutorService executor = Executors.newFixedThreadPool(2) ;
+ try {
+ promote_clash_active_writer(executor, activeWriterCommit) ;
+ }
+ finally {
+ executor.shutdown() ;
+ }
+ }
+
+ private void promote_clash_active_writer(ExecutorService executor, boolean activeWriterCommit) {
+ setReadCommitted(false) ;
+ Semaphore semaActiveWriterStart = new Semaphore(0) ;
+ Semaphore semaActiveWriterContinue = new Semaphore(0) ;
+ Semaphore semaPromoteTxnStart = new Semaphore(0) ;
+ Semaphore semaPromoteTxnContinue = new Semaphore(0) ;
+
+ DatasetGraph dsg = create() ;
+
+ // The "active writer".
+ Callable<Object> activeWriter = ()->{
+ dsg.begin(ReadWrite.WRITE) ;
+ semaActiveWriterStart.release(1) ;
+ // (*1)
+ semaActiveWriterContinue.acquireUninterruptibly(1) ;
+ if ( activeWriterCommit )
+ dsg.commit() ;
+ else
+ dsg.abort();
+ dsg.end() ;
+ return null ;
+ } ;
+
+ Future<Object> activeWriterFuture = executor.submit(activeWriter) ;
+ // Advance "active writer" to (*1), inside a write transaction and waiting.
+ // The transaction has been created and started.
+ semaActiveWriterStart.acquireUninterruptibly();
+
+ Callable<JenaException> attemptedPromote = ()->{
+ dsg.begin(ReadWrite.READ) ;
+ semaPromoteTxnStart.release(1) ;
+ // (*2)
+ semaPromoteTxnContinue.acquireUninterruptibly();
+ try {
+ // (*3)
+ dsg.add(q1) ;
+ return null ;
+ } catch (JenaException e) {
+ Class<?> c = getTransactionExceptionClass() ;
+ if ( ! e.getClass().equals(c) )
+ throw e ;
+ return e ;
+ }
+ } ;
+
+ Future<JenaException> attemptedPromoteFuture = executor.submit(attemptedPromote) ;
+ // Advance "attempted promote" to (*2), inside a read transaction, before attempting a promoting write.
+ // The transaction has been created and started.
+ semaPromoteTxnStart.acquireUninterruptibly();
+
+ // Advance "attempted promote" allowing it to go (*3) where it blocks
+ // This may happen at any time - as soon as it does, the "attempted promote" blocks.
+ semaPromoteTxnContinue.release(1);
+ // I don't know of a better way to ensure "attempted promote" is blocked.
+
+ Lib.sleep(100) ;
+ // Let the active writer go.
+ semaActiveWriterContinue.release(1);
+
+ try {
+ // Collect the active writer.
+ activeWriterFuture.get();
+
+ // (Ideal) and the attempted promotion should advance if the active writer aborts.
+ JenaException e = attemptedPromoteFuture.get() ;
+ if ( e != null )
+ throw e ;
+ } catch (InterruptedException | ExecutionException e1) { throw new RuntimeException(e1) ; }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/26109087/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TS_TransactionTDB.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TS_TransactionTDB.java b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TS_TransactionTDB.java
index e1f8af4..87bbf1e 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TS_TransactionTDB.java
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TS_TransactionTDB.java
@@ -41,7 +41,7 @@ import org.junit.runners.Suite ;
, TestTransactionUnionGraph.class
, TestMiscTDB.class
, TestTDBInternal.class
- , TestTransPromote.class
+ , TestTransPromoteTDB.class
, TestTransControl.class
, TestTransIsolation.class
})
http://git-wip-us.apache.org/repos/asf/jena/blob/26109087/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
deleted file mode 100644
index 5e62924..0000000
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
+++ /dev/null
@@ -1,391 +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.tdb.transaction ;
-
-import static org.junit.Assert.assertEquals ;
-import static org.junit.Assert.fail ;
-
-import java.util.concurrent.* ;
-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.sparql.core.DatasetGraph ;
-import org.apache.jena.sparql.core.Quad ;
-import org.apache.jena.sparql.sse.SSE ;
-import org.apache.jena.system.ThreadAction ;
-import org.apache.jena.system.ThreadTxn ;
-import org.apache.jena.system.Txn ;
-import org.apache.jena.tdb.TDB ;
-import org.apache.jena.tdb.TDBFactory ;
-import org.apache.jena.tdb.sys.SystemTDB ;
-import org.apache.log4j.Level ;
-import org.apache.log4j.Logger ;
-import org.junit.* ;
-
-/** Tests for transactions that start read and then promote to write */
-public class TestTransPromote {
-
- // Currently,
- // this feature is off and needs enabling via DatasetGraphTransaction.promotion
- // promotion is implicit when a write happens.
-
- // See beforeClass / afterClass.
-
- private static Logger logger1 = Logger.getLogger(SystemTDB.errlog.getName()) ;
- private static Level level1 ;
- private static Logger logger2 = Logger.getLogger(TDB.logInfoName) ;
- private static Level level2 ;
- static boolean stdPromotion ;
- static boolean stdReadCommitted ;
-
- @BeforeClass
- static public void beforeClass() {
- stdPromotion = DatasetGraphTransaction.promotion ;
- stdReadCommitted = DatasetGraphTransaction.readCommittedPromotion ;
- level1 = logger1.getLevel() ;
- level2 = logger2.getLevel() ;
- }
-
- @AfterClass
- static public void afterClass() {
- // Restore logging setting.
- logger2.setLevel(level2) ;
- logger1.setLevel(level1) ;
- DatasetGraphTransaction.promotion = stdPromotion ;
- DatasetGraphTransaction.readCommittedPromotion = stdReadCommitted ;
- }
-
- @Before
- public void before() {
- DatasetGraphTransaction.promotion = true ;
- DatasetGraphTransaction.readCommittedPromotion = true ;
- }
-
- @After
- public void after() {
- DatasetGraphTransaction.promotion = true ;
- DatasetGraphTransaction.readCommittedPromotion = true ;
- }
-
-
- private static Quad q1 = SSE.parseQuad("(_ :s :p1 1)") ;
- private static Quad q2 = SSE.parseQuad("(_ :s :p2 2)") ;
- private static Quad q3 = SSE.parseQuad("(_ :s :p3 3)") ;
-
- protected DatasetGraph create() {
- return TDBFactory.createDatasetGraph() ;
- }
-
- protected static void assertCount(long expected, DatasetGraph dsg) {
- dsg.begin(ReadWrite.READ) ;
- long x = Iter.count(dsg.find()) ;
- dsg.end() ;
- assertEquals(expected, x) ;
- }
-
- // "strict" = don't see intermedioate changes.
- // "readCommitted" = do see
-
- // Subclass / parameterized
-
- @Test public void promote_snapshot_01() { run_01(false) ; }
- @Test public void promote_readCommitted_01() { run_01(true) ; }
-
- // READ-add
- private void run_01(boolean b) {
- DatasetGraphTransaction.readCommittedPromotion = b ;
- DatasetGraph dsg = create() ;
-
- dsg.begin(ReadWrite.READ) ;
- dsg.add(q1) ;
- dsg.commit() ;
- dsg.end() ;
- }
-
- @Test public void promote_snapshot_02() { run_02(false) ; }
- @Test public void promote_readCommitted_02() { run_02(true) ; }
-
- // Previous transaction then READ-add
- private void run_02(boolean b) {
- DatasetGraphTransaction.readCommittedPromotion = b ;
- DatasetGraph dsg = create() ;
-
- dsg.begin(ReadWrite.READ) ;dsg.end() ;
-
- dsg.begin(ReadWrite.READ) ;
- dsg.add(q1) ;
- dsg.commit() ;
- dsg.end() ;
- }
-
- @Test public void promote_snapshot_03() { run_03(false) ; }
- @Test public void promote_readCommitted_03() { run_03(true) ; }
-
- private void run_03(boolean b) {
- DatasetGraphTransaction.readCommittedPromotion = b ;
- DatasetGraph dsg = create() ;
-
- dsg.begin(ReadWrite.WRITE) ;dsg.commit() ; dsg.end() ;
-
- dsg.begin(ReadWrite.READ) ;
- dsg.add(q1) ;
- dsg.commit() ;
- dsg.end() ;
- }
-
- @Test public void promote_snapshot_04() { run_04(false) ; }
- @Test public void promote_readCommitted_04() { run_04(true) ; }
-
- private void run_04(boolean b) {
- DatasetGraphTransaction.readCommittedPromotion = b ;
- DatasetGraph dsg = create() ;
-
- dsg.begin(ReadWrite.WRITE) ;dsg.abort() ; dsg.end() ;
-
- dsg.begin(ReadWrite.READ) ;
- dsg.add(q1) ;
- dsg.commit() ;
- dsg.end() ;
- }
-
- @Test public void promote_snapshot_05() { run_05(false) ; }
- @Test public void promote_readCommitted_05() { run_05(true) ; }
-
- private void run_05(boolean b) {
- DatasetGraphTransaction.readCommittedPromotion = b ;
- DatasetGraph dsg = create() ;
- dsg.begin(ReadWrite.READ) ;
- dsg.add(q1) ;
-
- // bad - forced abort.
- // Causes a WARN.
- logger1.setLevel(Level.ERROR) ;
- dsg.end() ;
- logger1.setLevel(level1) ;
-
- assertCount(0, dsg) ;
- }
-
- @Test public void promote_snapshot_06() { run_06(false) ; }
- @Test public void promote_readCommitted_06() { run_06(true) ; }
-
- // Async writer after promotion.
- private void run_06(boolean b) {
- DatasetGraphTransaction.readCommittedPromotion = b ;
- DatasetGraph dsg = create() ;
- AtomicInteger a = new AtomicInteger(0) ;
-
- Semaphore sema = new Semaphore(0) ;
- Thread t = new Thread(() -> {
- sema.release() ;
- Txn.executeWrite(dsg, () -> dsg.add(q3)) ;
- sema.release() ;
- }) ;
-
- dsg.begin(ReadWrite.READ) ;
- // Promote
- dsg.add(q1) ;
- t.start() ;
- // First release.
- sema.acquireUninterruptibly() ;
- // Thread blocked.
- dsg.add(q2) ;
- dsg.commit() ;
- dsg.end() ;
-
- // Until thread exits.
- sema.acquireUninterruptibly() ;
- assertCount(3, dsg) ;
- }
-
- @Test public void promote_snapshot_07() { run_07(false) ; }
- @Test public void promote_readCommitted_07() { run_07(true) ; }
-
- // Async writer after promotion.
- private void run_07(boolean b) {
- DatasetGraphTransaction.readCommittedPromotion = b ;
- DatasetGraph dsg = create() ;
- // Start long running reader.
- ThreadAction tt = ThreadTxn.threadTxnRead(dsg, () -> {
- long x = Iter.count(dsg.find()) ;
- if ( x != 0 )
- throw new RuntimeException() ;
- }) ;
-
- // Start R->W here
- dsg.begin(ReadWrite.READ) ;
- dsg.add(q1) ;
- dsg.add(q2) ;
- dsg.commit() ;
- dsg.end() ;
- tt.run() ;
- }
-
- @Test public void promote_snapshot_08() { run_08(false) ; }
- @Test public void promote_readCommitted_08() { run_08(true) ; }
-
- // Async writer after promotion trasnaction ends.
- private void run_08(boolean b) {
- DatasetGraphTransaction.readCommittedPromotion = b ;
- DatasetGraph dsg = create() ;
- // Start R->W here
- dsg.begin(ReadWrite.READ) ;
- dsg.add(q1) ;
- dsg.add(q2) ;
- dsg.commit() ;
- dsg.end() ;
- Txn.executeRead(dsg, () -> {
- long x = Iter.count(dsg.find()) ;
- assertEquals(2, x) ;
- }) ;
- }
-
- // Tests for XXX Read-committed yes/no (false = snapshot isolation, true = read committed),
- // and whether the other transaction commits (true) or aborts (false).
-
- @Test
- public void promote_10() { promote_readCommit_txnCommit(true, true) ; }
-
- @Test
- public void promote_11() { promote_readCommit_txnCommit(true, false) ; }
-
- @Test(expected = TDBTransactionException.class)
- public void promote_12() { promote_readCommit_txnCommit(false, true) ; }
-
- @Test
- public void promote_13() { promote_readCommit_txnCommit(false, false) ; }
-
- private void promote_readCommit_txnCommit(boolean allowReadCommitted, boolean asyncCommit) {
- logger2.setLevel(Level.ERROR);
- DatasetGraphTransaction.readCommittedPromotion = allowReadCommitted ;
- DatasetGraph dsg = create() ;
-
- ThreadAction tt = asyncCommit?
- ThreadTxn.threadTxnWrite(dsg, () -> dsg.add(q3) ) :
- ThreadTxn.threadTxnWriteAbort(dsg, () -> dsg.add(q3)) ;
-
- dsg.begin(ReadWrite.READ) ;
- // Other runs
- tt.run() ;
- // Can promote if readCommited
- // Can't promote if not readCommited
- dsg.add(q1) ;
- if ( ! allowReadCommitted && asyncCommit )
- fail("Should not be here") ;
-
- assertEquals(asyncCommit, dsg.contains(q3)) ;
- dsg.commit() ;
- dsg.end() ;
- logger2.setLevel(level2);
- }
-
- // Active writer commits -> no promotion.
- @Test(expected=TDBTransactionException.class)
- public void promote_active_writer_1() throws InterruptedException, ExecutionException {
- promote_active_writer(true) ;
- }
-
- // Active writer aborts -> promotion.
- @Test
- public void promote_active_writer_2() throws InterruptedException, ExecutionException {
- // Active writer aborts -> promotion possible (but not implemented that way).
- promote_active_writer(false) ;
- }
-
- private void promote_active_writer(boolean activeWriterCommit) {
- ExecutorService executor = Executors.newFixedThreadPool(2) ;
- try {
- promote_clash_active_writer(executor, activeWriterCommit) ;
- }
- finally {
- executor.shutdown() ;
- }
- }
-
- private void promote_clash_active_writer(ExecutorService executor, boolean activeWriterCommit) {
- DatasetGraphTransaction.readCommittedPromotion = false ;
- Semaphore semaActiveWriterStart = new Semaphore(0) ;
- Semaphore semaActiveWriterContinue = new Semaphore(0) ;
- Semaphore semaPromoteTxnStart = new Semaphore(0) ;
- Semaphore semaPromoteTxnContinue = new Semaphore(0) ;
-
- DatasetGraph dsg = create() ;
-
- // The "active writer".
- Callable<Object> activeWriter = ()->{
- dsg.begin(ReadWrite.WRITE) ;
- semaActiveWriterStart.release(1) ;
- // (*1)
- semaActiveWriterContinue.acquireUninterruptibly(1) ;
- if ( activeWriterCommit )
- dsg.commit() ;
- else
- dsg.abort();
- dsg.end() ;
- return null ;
- } ;
-
- Future<Object> activeWriterFuture = executor.submit(activeWriter) ;
- // Advance "active writer" to (*1), inside a write transaction and waiting.
- // The transaction has been created and started.
- semaActiveWriterStart.acquireUninterruptibly();
-
- Callable<TDBTransactionException> attemptedPromote = ()->{
- dsg.begin(ReadWrite.READ) ;
- semaPromoteTxnStart.release(1) ;
- // (*2)
- semaPromoteTxnContinue.acquireUninterruptibly();
- try {
- // (*3)
- dsg.add(q1) ;
- //System.err.println("PROMOTED");
- return null ;
- } catch (TDBTransactionException e) {
- //System.err.println("NOT PROMOTED");
- return e ;
- }
- } ;
-
- Future<TDBTransactionException> attemptedPromoteFuture = executor.submit(attemptedPromote) ;
- // Advance "attempted promote" to (*2), inside a read transaction, before attempting a promoting write.
- // The transaction has been created and started.
- semaPromoteTxnStart.acquireUninterruptibly();
-
- // Advance "attempted promote" allowing it to go (*3) where it blocks
- // This may happen at any time - as soon as it does, the "attempted promote" blocks.
- semaPromoteTxnContinue.release(1);
- // I don't know of a better way to ensure "attempted promote" is blocked.
-
- Lib.sleep(100) ;
- // Let the active writer go.
- semaActiveWriterContinue.release(1);
-
- try {
- // Collect the active writer.
- activeWriterFuture.get();
-
- // (Ideal) and the attempted promotion should advance if the active writer aborts.
- TDBTransactionException e = attemptedPromoteFuture.get() ;
- if ( e != null )
- throw e ;
- } catch (InterruptedException | ExecutionException e1) { throw new RuntimeException(e1) ; }
- }
-}
http://git-wip-us.apache.org/repos/asf/jena/blob/26109087/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromoteTDB.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromoteTDB.java b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromoteTDB.java
new file mode 100644
index 0000000..61ba5f1
--- /dev/null
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromoteTDB.java
@@ -0,0 +1,72 @@
+/*
+ * 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.tdb.transaction ;
+
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.transaction.AbstractTestTransPromote ;
+import org.apache.jena.tdb.TDB ;
+import org.apache.jena.tdb.TDBFactory ;
+import org.apache.jena.tdb.sys.SystemTDB ;
+import org.apache.jena.tdb.transaction.DatasetGraphTransaction ;
+import org.apache.jena.tdb.transaction.TDBTransactionException ;
+import org.apache.log4j.Logger ;
+
+/** Tests for transactions that start read and then promote to write -- TDB */
+public class TestTransPromoteTDB extends AbstractTestTransPromote {
+ public TestTransPromoteTDB() {
+ super(getLoggers()) ;
+ }
+
+ @Override
+ protected DatasetGraph create() {
+ return TDBFactory.createDatasetGraph() ;
+ }
+
+ private static Logger[] getLoggers() {
+ return new Logger[]{
+ Logger.getLogger(SystemTDB.errlog.getName()),
+ Logger.getLogger(TDB.logInfoName)
+ } ;
+ }
+
+ @Override
+ protected void setPromotion(boolean b) {
+ DatasetGraphTransaction.promotion = b ;
+ }
+
+ @Override
+ protected boolean getPromotion() {
+ return DatasetGraphTransaction.promotion ;
+ }
+
+ @Override
+ protected void setReadCommitted(boolean b) {
+ DatasetGraphTransaction.readCommittedPromotion = b ;
+ }
+
+ @Override
+ protected boolean getReadCommitted() {
+ return DatasetGraphTransaction.readCommittedPromotion ;
+ }
+
+ @Override
+ protected Class<?> getTransactionExceptionClass() {
+ return TDBTransactionException.class ;
+ }
+}
\ No newline at end of file
[3/6] jena git commit: JENA-1237: Tests (TDB and TIM)
Posted by an...@apache.org.
JENA-1237: Tests (TDB and TIM)
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/51175d27
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/51175d27
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/51175d27
Branch: refs/heads/master
Commit: 51175d27768955ed1918b79ea7f046723e5c3173
Parents: f9f2870
Author: Andy Seaborne <an...@apache.org>
Authored: Sat Sep 17 17:03:31 2016 +0100
Committer: Andy Seaborne <an...@apache.org>
Committed: Sat Sep 17 17:11:31 2016 +0100
----------------------------------------------------------------------
.../jena/sparql/core/mem/TS_DatasetTxnMem.java | 3 +-
.../mem/TestDatasetGraphInMemoryIsolation.java | 30 +++++++++++
.../AbstractTestTransactionIsolation.java | 55 ++++++++++++++++++++
.../AbstractTestTransactionLifecycle.java | 2 -
.../tdb/transaction/TransactionManager.java | 2 +-
.../jena/tdb/transaction/TS_TransactionTDB.java | 1 +
.../tdb/transaction/TestTransIsolation.java | 32 ++++++++++++
.../jena/tdb/transaction/TestTransPromote.java | 5 +-
8 files changed, 122 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/51175d27/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TS_DatasetTxnMem.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TS_DatasetTxnMem.java b/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TS_DatasetTxnMem.java
index 815c8e5..f3d795b 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TS_DatasetTxnMem.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TS_DatasetTxnMem.java
@@ -39,6 +39,7 @@ import org.junit.runners.Suite.SuiteClasses;
TestDatasetGraphInMemoryTransactions.class,
TestDatasetGraphInMemoryFind.class,
- TestDatasetGraphInMemoryFindPattern.class
+ TestDatasetGraphInMemoryFindPattern.class,
+ TestDatasetGraphInMemoryIsolation.class
})
public class TS_DatasetTxnMem {}
http://git-wip-us.apache.org/repos/asf/jena/blob/51175d27/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryIsolation.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryIsolation.java b/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryIsolation.java
new file mode 100644
index 0000000..12b0173
--- /dev/null
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryIsolation.java
@@ -0,0 +1,30 @@
+/*
+ * 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.sparql.core.mem;
+
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.transaction.AbstractTestTransactionIsolation ;
+
+public class TestDatasetGraphInMemoryIsolation extends AbstractTestTransactionIsolation {
+
+ @Override
+ protected DatasetGraph create() {
+ return new DatasetGraphInMemory() ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/51175d27/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransactionIsolation.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransactionIsolation.java b/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransactionIsolation.java
new file mode 100644
index 0000000..85a574f
--- /dev/null
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransactionIsolation.java
@@ -0,0 +1,55 @@
+/*
+ * 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.sparql.transaction;
+
+import static org.apache.jena.query.ReadWrite.* ;
+
+import org.apache.jena.atlas.iterator.Iter ;
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.core.Quad ;
+import org.apache.jena.sparql.sse.SSE ;
+import org.apache.jena.system.ThreadAction ;
+import org.apache.jena.system.ThreadTxn ;
+import org.junit.Assert ;
+import org.junit.Test ;
+
+/** Isolation tests */
+public abstract class AbstractTestTransactionIsolation {
+
+ protected abstract DatasetGraph create() ;
+ static Quad q1 = SSE.parseQuad("(_ :s :p 111)") ;
+
+ @Test
+ public void isolation_01() {
+ // Start a read transaction on another thread.
+ // The transaction has begin() by the time threadTxnRead
+ // returns but the action of the ThreadTxn is not triggered
+ // until other.run() is called.
+ DatasetGraph dsg = create() ;
+ ThreadAction other = ThreadTxn.threadTxnRead(dsg, ()-> {
+ long x = Iter.count(dsg.find()) ;
+ Assert.assertEquals(0, x) ;
+ }) ;
+ dsg.begin(WRITE) ;
+ dsg.add(q1) ;
+ dsg.commit() ;
+ dsg.end() ;
+ other.run() ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/51175d27/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransactionLifecycle.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransactionLifecycle.java b/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransactionLifecycle.java
index d8b8567..32b8ca3 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransactionLifecycle.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/transaction/AbstractTestTransactionLifecycle.java
@@ -252,8 +252,6 @@ public abstract class AbstractTestTransactionLifecycle extends BaseTest
@Test
public void transaction_err_12() { testAbortCommit(WRITE) ; }
-
-
private void read1(Dataset ds) {
ds.begin(ReadWrite.READ) ;
assertTrue(ds.isInTransaction()) ;
http://git-wip-us.apache.org/repos/asf/jena/blob/51175d27/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
index 60c4d88..235f3b9 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/transaction/TransactionManager.java
@@ -380,7 +380,7 @@ public class TransactionManager
synchronized
private DatasetGraphTxn promote2$(DatasetGraphTxn dsgtxn, boolean readCommited) {
Transaction txn = dsgtxn.getTransaction() ;
- // Writers may have happened between the first check of of the active writers may have committed.
+ // Writers may have happened between the first check of the active writers may have committed.
if ( txn.getVersion() != version.get() ) {
releaseWriterLock();
throw new TDBTransactionException("Active writer changed the dataset - can't promote") ;
http://git-wip-us.apache.org/repos/asf/jena/blob/51175d27/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TS_TransactionTDB.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TS_TransactionTDB.java b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TS_TransactionTDB.java
index 7a9d288..e1f8af4 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TS_TransactionTDB.java
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TS_TransactionTDB.java
@@ -43,6 +43,7 @@ import org.junit.runners.Suite ;
, TestTDBInternal.class
, TestTransPromote.class
, TestTransControl.class
+ , TestTransIsolation.class
})
public class TS_TransactionTDB
{
http://git-wip-us.apache.org/repos/asf/jena/blob/51175d27/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransIsolation.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransIsolation.java b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransIsolation.java
new file mode 100644
index 0000000..ba2ff10
--- /dev/null
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransIsolation.java
@@ -0,0 +1,32 @@
+/*
+ * 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.tdb.transaction;
+
+import org.apache.jena.sparql.core.DatasetGraph ;
+import org.apache.jena.sparql.transaction.AbstractTestTransactionIsolation ;
+import org.apache.jena.tdb.TDBFactory ;
+
+public class TestTransIsolation extends AbstractTestTransactionIsolation {
+
+ @Override
+ protected DatasetGraph create() {
+ return TDBFactory.createDatasetGraph() ;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/51175d27/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
----------------------------------------------------------------------
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
index 1d1d686..5e62924 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/transaction/TestTransPromote.java
@@ -45,7 +45,7 @@ public class TestTransPromote {
// Currently,
// this feature is off and needs enabling via DatasetGraphTransaction.promotion
- // promotiion is implicit whe a write happens.
+ // promotion is implicit when a write happens.
// See beforeClass / afterClass.
@@ -62,9 +62,6 @@ public class TestTransPromote {
stdReadCommitted = DatasetGraphTransaction.readCommittedPromotion ;
level1 = logger1.getLevel() ;
level2 = logger2.getLevel() ;
-
- // logger1.setLevel(Level.ERROR) ;
- // logger2.setLevel(Level.ERROR) ;
}
@AfterClass