You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by an...@apache.org on 2018/01/04 20:46:22 UTC
[08/14] jena git commit: Fix to work with tests. Cleanup.
Fix to work with tests. Cleanup.
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/edab900a
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/edab900a
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/edab900a
Branch: refs/heads/master
Commit: edab900abf7fc05d7ffc8e9fcb7b41d1b1647625
Parents: d6770ea
Author: Andy Seaborne <an...@apache.org>
Authored: Sun Dec 31 20:49:18 2017 +0000
Committer: Andy Seaborne <an...@apache.org>
Committed: Tue Jan 2 15:58:30 2018 +0000
----------------------------------------------------------------------
.../java/org/apache/jena/query/Dataset.java | 7 -
.../java/org/apache/jena/query/TxnType.java | 21 +-
.../jena/sparql/core/DatasetGraphMap.java | 18 +-
.../jena/sparql/core/DatasetGraphMapLink.java | 17 +-
.../jena/sparql/core/DatasetGraphOne.java | 18 +-
.../jena/sparql/core/DatasetGraphSink.java | 5 +-
.../jena/sparql/core/DatasetGraphWithLock.java | 3 +
.../jena/sparql/core/DatasetGraphZero.java | 8 +-
.../apache/jena/sparql/core/DatasetImpl.java | 36 +-
.../apache/jena/sparql/core/Transactional.java | 4 +-
.../jena/sparql/core/TransactionalLock.java | 72 +-
.../jena/sparql/core/TransactionalMutex.java | 75 ---
.../sparql/core/TransactionalNotSupported.java | 32 +-
.../core/TransactionalNotSupportedMixin.java | 17 +-
.../jena/sparql/core/TransactionalNull.java | 55 +-
.../sparql/core/mem/DatasetGraphInMemory.java | 41 +-
.../java/org/apache/jena/system/TxnCounter.java | 191 ++++--
.../org/apache/jena/sparql/core/TS_Core.java | 1 -
.../sparql/core/TestDatasetGraphWithLock.java | 30 -
.../core/mem/TestDatasetGraphInMemoryLock.java | 4 +-
.../transaction/AbstractTestTransPromote.java | 51 +-
.../AbstractTestTransactionLifecycle.java | 187 ++++-
.../jena/sparql/transaction/TS_Transaction.java | 2 -
.../TestTransactionDSGWithLockNoAbort.java | 41 --
.../TestTransactionDSGWithLockWithAbort.java | 38 --
.../transaction/TestTransactionSupport.java | 6 +-
.../java/org/apache/jena/atlas/lib/Lib.java | 11 +
.../jena/dboe/transaction/txn/Transaction.java | 5 +-
.../transaction/txn/TransactionCoordinator.java | 28 +-
.../dboe/transaction/txn/TransactionalBase.java | 23 +-
.../transaction/TestTransactionLifecycle.java | 179 ++++-
.../transaction/TestTransactionLifecycle2.java | 8 +-
.../apache/jena/fuseki/servlets/HttpAction.java | 2 +-
.../jena/rdfconnection/RDFConnectionLocal.java | 26 +-
.../rdfconnection/RDFConnectionModular.java | 27 +-
.../jena/rdfconnection/RDFConnectionRemote.java | 71 +-
.../apache/jena/sdb/store/DatasetGraphSDB.java | 25 +-
.../org/apache/jena/tdb/StoreConnection.java | 8 +-
.../apache/jena/tdb/store/DatasetGraphTDB.java | 18 +-
.../jena/tdb/transaction/BlockMgrJournal.java | 2 +-
.../transaction/DatasetGraphTransaction.java | 52 +-
.../jena/tdb/transaction/DatasetGraphTxn.java | 7 +
.../jena/tdb/transaction/Transaction.java | 9 +-
.../tdb/transaction/TransactionManager.java | 92 ++-
.../jena/tdb/extra/T_TDBWriteTransaction.java | 151 -----
.../jena/tdb/extra/T_TimeoutTDBPattern.java | 112 ---
.../apache/jena/tdb/extra/T_TransSystem.java | 674 -------------------
.../tdb/extra/T_TransSystemMultiDatasets.java | 553 ---------------
.../jena/tdb/extra/T_TxnDeadlockTest.java | 141 ----
.../tdb/store/AbstractStoreConnections.java | 30 +-
.../AbstractTestObjectFileTrans.java | 2 +-
.../AbstractTestObjectFileTransComplex.java | 2 +-
.../tdb/transaction/AbstractTestTransSeq.java | 6 -
.../tdb/transaction/TestTransPromoteTDB.java | 5 +-
.../tdb/transaction/TestTransactionTDB.java | 3 +-
55 files changed, 943 insertions(+), 2309 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/main/java/org/apache/jena/query/Dataset.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/query/Dataset.java b/jena-arq/src/main/java/org/apache/jena/query/Dataset.java
index 38b1c22..6f8bc0e 100644
--- a/jena-arq/src/main/java/org/apache/jena/query/Dataset.java
+++ b/jena-arq/src/main/java/org/apache/jena/query/Dataset.java
@@ -32,13 +32,6 @@ import org.apache.jena.sparql.util.Context ;
public interface Dataset extends Transactional
{
- // TEMP
-
- @Override
- public default void begin(TxnType type) { throw new UnsupportedOperationException("Dataset.begin(TxnType)"); }
-
-
-
/** Get the default graph as a Jena Model */
public Model getDefaultModel() ;
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/main/java/org/apache/jena/query/TxnType.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/query/TxnType.java b/jena-arq/src/main/java/org/apache/jena/query/TxnType.java
index 3679414..39d5dc8 100644
--- a/jena-arq/src/main/java/org/apache/jena/query/TxnType.java
+++ b/jena-arq/src/main/java/org/apache/jena/query/TxnType.java
@@ -18,6 +18,8 @@
package org.apache.jena.query;
+import java.util.Objects;
+
import org.apache.jena.sparql.JenaTransactionException;
public enum TxnType {
@@ -46,7 +48,7 @@ public enum TxnType {
*/
READ, WRITE, READ_PROMOTE, READ_COMMITTED_PROMOTE
;
-
+ /** Convert a {@link ReadWrite} mode to {@code TxnType} */
public static TxnType convert(ReadWrite rw) {
switch(rw) {
case READ: return READ;
@@ -54,11 +56,22 @@ public enum TxnType {
default: throw new NullPointerException();
}
}
- public static ReadWrite convert(TxnType mode) {
- switch(mode) {
+ /** Convert a {@code TxnType} mode to {@link ReadWrite} : "promote" not supported. */
+ public static ReadWrite convert(TxnType txnType) {
+ Objects.requireNonNull(txnType);
+ switch(txnType) {
case READ: return ReadWrite.READ;
case WRITE: return ReadWrite.WRITE;
- default: throw new JenaTransactionException("Incompatible mode: "+mode);
+ default: throw new JenaTransactionException("Incompatible mode: "+txnType);
}
}
+ /**
+ * Translate a {@code TxnType} to it's initial {@link ReadWrite} mode.
+ * {@code WRITE -> WRITE}, {@code READ* -> READ} regardless of promotion setting.
+ */
+ public static ReadWrite initial(TxnType txnType) {
+ Objects.requireNonNull(txnType);
+ return (txnType == TxnType.WRITE) ? ReadWrite.WRITE : ReadWrite.READ;
+ }
+
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphMap.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphMap.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphMap.java
index 24d3e04..d25aad1 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphMap.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphMap.java
@@ -30,6 +30,7 @@ import org.apache.jena.graph.Graph ;
import org.apache.jena.graph.Node ;
import org.apache.jena.graph.Triple ;
import org.apache.jena.query.ReadWrite ;
+import org.apache.jena.query.TxnType;
import org.apache.jena.sparql.ARQException ;
import org.apache.jena.sparql.core.DatasetGraphFactory.GraphMaker ;
import org.apache.jena.sparql.graph.GraphUnionRead ;
@@ -69,13 +70,18 @@ public class DatasetGraphMap extends DatasetGraphTriplesQuads
// ----
private final Transactional txn = TransactionalLock.createMRSW() ;
- @Override public void begin(ReadWrite mode) { txn.begin(mode) ; }
- @Override public void commit() { txn.commit() ; }
- @Override public void abort() { txn.abort() ; }
- @Override public boolean isInTransaction() { return txn.isInTransaction() ; }
+ @Override public void begin() { txn.begin(); }
+ @Override public void begin(TxnType txnType) { txn.begin(txnType); }
+ @Override public void begin(ReadWrite mode) { txn.begin(mode); }
+ @Override public boolean promote() { return txn.promote(); }
+ @Override public void commit() { txn.commit(); }
+ @Override public void abort() { txn.abort(); }
+ @Override public boolean isInTransaction() { return txn.isInTransaction(); }
@Override public void end() { txn.end(); }
- @Override public boolean supportsTransactions() { return true ; }
- @Override public boolean supportsTransactionAbort() { return false ; }
+ @Override public ReadWrite transactionMode() { return txn.transactionMode(); }
+ @Override public TxnType transactionType() { return txn.transactionType(); }
+ @Override public boolean supportsTransactions() { return true; }
+ @Override public boolean supportsTransactionAbort() { return false; }
// ----
@Override
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphMapLink.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphMapLink.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphMapLink.java
index 605778a..f429192 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphMapLink.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphMapLink.java
@@ -25,6 +25,7 @@ import java.util.Map ;
import org.apache.jena.graph.Graph ;
import org.apache.jena.graph.Node ;
import org.apache.jena.query.ReadWrite ;
+import org.apache.jena.query.TxnType;
import org.apache.jena.sparql.SystemARQ ;
import org.apache.jena.sparql.core.DatasetGraphFactory.GraphMaker ;
import org.apache.jena.sparql.graph.GraphUnionRead ;
@@ -119,7 +120,6 @@ public class DatasetGraphMapLink extends DatasetGraphCollection
// ----
private final Transactional txn = TransactionalLock.createMRSW() ;
- @Override public void begin(ReadWrite mode) { txn.begin(mode) ; }
@Override
public void commit() {
@@ -127,11 +127,18 @@ public class DatasetGraphMapLink extends DatasetGraphCollection
txn.commit() ;
}
- @Override public void abort() { txn.abort() ; }
- @Override public boolean isInTransaction() { return txn.isInTransaction() ; }
+ @Override public void begin() { txn.begin(); }
+ @Override public void begin(TxnType txnType) { txn.begin(txnType); }
+ @Override public void begin(ReadWrite mode) { txn.begin(mode); }
+ @Override public boolean promote() { return txn.promote(); }
+ //@Override public void commit() { txn.commit(); }
+ @Override public void abort() { txn.abort(); }
+ @Override public boolean isInTransaction() { return txn.isInTransaction(); }
@Override public void end() { txn.end(); }
- @Override public boolean supportsTransactions() { return true ; }
- @Override public boolean supportsTransactionAbort() { return false ; }
+ @Override public ReadWrite transactionMode() { return txn.transactionMode(); }
+ @Override public TxnType transactionType() { return txn.transactionType(); }
+ @Override public boolean supportsTransactions() { return true; }
+ @Override public boolean supportsTransactionAbort() { return false; }
// ----
@Override
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphOne.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphOne.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphOne.java
index 8c487be..601789e 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphOne.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphOne.java
@@ -28,6 +28,7 @@ import org.apache.jena.graph.Graph;
import org.apache.jena.graph.Node;
import org.apache.jena.graph.Triple;
import org.apache.jena.query.ReadWrite;
+import org.apache.jena.query.TxnType;
/** DatasetGraph of a single graph as default graph.
* <p>
@@ -72,14 +73,17 @@ public class DatasetGraphOne extends DatasetGraphBaseFind {
supportsAbort = false;
}
- @Override public void begin(ReadWrite mode) { txn.begin(mode) ; }
- @Override public void commit() { txn.commit() ; }
- @Override public void abort() { txn.abort() ; }
- @Override public boolean isInTransaction() { return txn.isInTransaction() ; }
+ @Override public void begin(TxnType txnType) { txn.begin(txnType); }
+ @Override public void begin(ReadWrite mode) { txn.begin(mode); }
+ @Override public void commit() { txn.commit(); }
+ @Override public void abort() { txn.abort(); }
+ @Override public boolean isInTransaction() { return txn.isInTransaction(); }
@Override public void end() { txn.end(); }
- @Override public boolean supportsTransactions() { return true ; }
- @Override public boolean supportsTransactionAbort() { return supportsAbort ; }
-
+ @Override public ReadWrite transactionMode() { return txn.transactionMode(); }
+ @Override public TxnType transactionType() { return txn.transactionType(); }
+ @Override public boolean supportsTransactions() { return true; }
+ // Because there are never any changes, abort() means "finish".
+ @Override public boolean supportsTransactionAbort() { return true; }
@Override
public boolean containsGraph(Node graphNode) {
if ( isDefaultGraph(graphNode) )
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphSink.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphSink.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphSink.java
index 64735d0..b8852a1 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphSink.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphSink.java
@@ -24,6 +24,7 @@ import org.apache.jena.atlas.iterator.Iter;
import org.apache.jena.graph.Graph;
import org.apache.jena.graph.Node;
import org.apache.jena.query.ReadWrite;
+import org.apache.jena.query.TxnType;
import org.apache.jena.sparql.graph.GraphSink;
@@ -41,13 +42,15 @@ public class DatasetGraphSink extends DatasetGraphBaseFind {
public DatasetGraphSink() {}
private TransactionalNull txn = TransactionalNull.create();
+ @Override public void begin(TxnType txnType) { txn.begin(txnType); }
@Override public void begin(ReadWrite mode) { txn.begin(mode); }
@Override public void commit() { txn.commit(); }
@Override public void abort() { txn.abort(); }
@Override public boolean isInTransaction() { return txn.isInTransaction(); }
@Override public void end() { txn.end(); }
+ @Override public ReadWrite transactionMode() { return txn.transactionMode(); }
+ @Override public TxnType transactionType() { return txn.transactionType(); }
@Override public boolean supportsTransactions() { return true; }
- // Because there are never any changes, abort() means "finish".
@Override public boolean supportsTransactionAbort() { return true; }
@Override
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWithLock.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWithLock.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWithLock.java
index 86ae484..815414e 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWithLock.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphWithLock.java
@@ -31,7 +31,10 @@ import org.apache.jena.sparql.util.Context ;
* behaviour, that is the application see transaction but they are not durable.
* Only provides multiple-reader OR single-writer, and no write-transaction
* abort.
+ * @deprecated Will be removed.
*/
+// NOT USED
+@Deprecated
public class DatasetGraphWithLock extends DatasetGraphTrackActive implements Sync {
private final ThreadLocal<Boolean> writeTxn = ThreadLocal.withInitial(()->false) ;
private final DatasetGraph dsg ;
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphZero.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphZero.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphZero.java
index a5a813b..4ada686 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphZero.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetGraphZero.java
@@ -24,6 +24,7 @@ import org.apache.jena.atlas.iterator.Iter;
import org.apache.jena.graph.Graph;
import org.apache.jena.graph.Node;
import org.apache.jena.query.ReadWrite;
+import org.apache.jena.query.TxnType;
import org.apache.jena.sparql.graph.GraphZero;
/** An always empty {@link DatasetGraph}.
@@ -40,14 +41,19 @@ public class DatasetGraphZero extends DatasetGraphBaseFind {
public DatasetGraphZero() {}
private TransactionalNull txn = TransactionalNull.create();
+ @Override public void begin() { txn.begin(); }
+ @Override public void begin(TxnType txnType) { txn.begin(txnType); }
@Override public void begin(ReadWrite mode) { txn.begin(mode); }
+ @Override public boolean promote() { return txn.promote(); }
@Override public void commit() { txn.commit(); }
@Override public void abort() { txn.abort(); }
@Override public boolean isInTransaction() { return txn.isInTransaction(); }
@Override public void end() { txn.end(); }
+ @Override public ReadWrite transactionMode() { return txn.transactionMode(); }
+ @Override public TxnType transactionType() { return txn.transactionType(); }
@Override public boolean supportsTransactions() { return true; }
- // Because there are never any changes, abort() means "finish".
@Override public boolean supportsTransactionAbort() { return true; }
+
@Override
public Iterator<Node> listGraphNodes() {
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetImpl.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetImpl.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetImpl.java
index 00e419a..dfb8262 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetImpl.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/DatasetImpl.java
@@ -25,6 +25,7 @@ import org.apache.jena.graph.Node ;
import org.apache.jena.graph.NodeFactory ;
import org.apache.jena.query.Dataset ;
import org.apache.jena.query.ReadWrite ;
+import org.apache.jena.query.TxnType;
import org.apache.jena.rdf.model.Model ;
import org.apache.jena.rdf.model.ModelFactory ;
import org.apache.jena.shared.Lock ;
@@ -96,13 +97,15 @@ public class DatasetImpl implements Dataset
}
@Override
- public boolean supportsTransactions() {
- return dsg.supportsTransactions() ;
+ public void begin() {
+ checkTransactional();
+ transactional.begin();
}
@Override
- public boolean supportsTransactionAbort() {
- return dsg.supportsTransactionAbort() ;
+ public void begin(TxnType txnType) {
+ checkTransactional();
+ transactional.begin(txnType);
}
@Override
@@ -110,6 +113,31 @@ public class DatasetImpl implements Dataset
checkTransactional();
transactional.begin(mode);
}
+
+ @Override
+ public boolean promote() {
+ return transactional.promote();
+ }
+
+ @Override
+ public ReadWrite transactionMode() {
+ return transactional.transactionMode();
+ }
+
+ @Override
+ public TxnType transactionType() {
+ return transactional.transactionType();
+ }
+
+ @Override
+ public boolean supportsTransactions() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsTransactionAbort() {
+ return false;
+ }
/** Say whether a transaction is active */
@Override
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/main/java/org/apache/jena/sparql/core/Transactional.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/Transactional.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/Transactional.java
index 8425a18..08bc230 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/Transactional.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/Transactional.java
@@ -130,8 +130,8 @@ public interface Transactional
public void end() ;
/** Return the current mode of the transaction - "read" or "write" */
- //public ReadWrite transactionMode();
- public default ReadWrite transactionMode() { throw new JenaTransactionException("Not implemented"); }
+ public ReadWrite transactionMode();
+ //public default ReadWrite transactionMode() { throw new JenaTransactionException("Not implemented"); }
/** Return the transaction type used in {@code begin(TxnType)}. */
//public TxnMode transactionMode();
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalLock.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalLock.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalLock.java
index ad2ad3c..14d04b8 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalLock.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalLock.java
@@ -18,8 +18,7 @@
package org.apache.jena.sparql.core;
-import java.util.Objects ;
-
+import org.apache.jena.atlas.lib.Lib;
import org.apache.jena.query.ReadWrite ;
import org.apache.jena.query.TxnType;
import org.apache.jena.shared.Lock ;
@@ -35,29 +34,40 @@ import org.apache.jena.sparql.JenaTransactionException ;
* <pre>
* private final Transactional txn = TransactionalLock.createMRSW() ;
* {@literal @}Override public void begin(TxnType txnType) { txn.begin(txnType) ; }
- * {@literal @}Override public void begin(ReadWrite mode) { txn.begin(mode) ; }
- * {@literal @}Override public boolean promote() { return txn.promote() ; }
- * {@literal @}Override public void commit() { txn.commit() ; }
- * {@literal @}Override public void abort() { txn.abort() ; }
- * {@literal @}Override public boolean isInTransaction() { return txn.isInTransaction() ; }
+ * {@literal @}Override public void begin() { txn.begin(); }
+ * {@literal @}Override public void begin(TxnType txnType) { txn.begin(txnType); }
+ * {@literal @}Override public void begin(ReadWrite mode) { txn.begin(mode); }
+ * {@literal @}Override public boolean promote() { return txn.promote(); }
+ * {@literal @}Override public void commit() { txn.commit(); }
+ * {@literal @}Override public void abort() { txn.abort(); }
+ * {@literal @}Override public boolean isInTransaction() { return txn.isInTransaction(); }
* {@literal @}Override public void end() { txn.end(); }
- * {@literal @}Override public boolean supportsTransactions() { return true ; }
- * {@literal @}Override public boolean supportsTransactionAbort() { return false ; }
+ * {@literal @}Override public ReadWrite transactionMode() { return txn.transactionMode(); }
+ * {@literal @}Override public TxnType transactionType() { return txn.transactionType(); }
+ * {@literal @}Override public boolean supportsTransactions() { return true; }
+ * {@literal @}Override public boolean supportsTransactionAbort() { return true; }
* </pre>
*/
public class TransactionalLock implements Transactional {
/*
- private final Transactional txn = TransactionalLock.createMRSW() ;
- @Override public void begin(ReadWrite mode) { txn.begin(mode) ; }
- @Override public void commit() { txn.commit() ; }
- @Override public void abort() { txn.abort() ; }
- @Override public boolean isInTransaction() { return txn.isInTransaction() ; }
- @Override public void end() { txn.end(); }
- @Override public boolean supportsTransactions() { return true ; }
- @Override public boolean supportsTransactionAbort() { return false ; }
+ private final Transactional txn = TransactionalLock.createMRSW() ;
+ @Override public void begin() { txn.begin(); }
+ @Override public void begin(TxnType txnType) { txn.begin(txnType); }
+ @Override public void begin(ReadWrite mode) { txn.begin(mode); }
+ @Override public boolean promote() { return txn.promote(); }
+ @Override public void commit() { txn.commit(); }
+ @Override public void abort() { txn.abort(); }
+ @Override public boolean isInTransaction() { return txn.isInTransaction(); }
+ @Override public void end() { txn.end(); }
+ @Override public ReadWrite transactionMode() { return txn.transactionMode(); }
+ @Override public TxnType transactionType() { return txn.transactionType(); }
+ @Override public boolean supportsTransactions() { return true; }
+ @Override public boolean supportsTransactionAbort() { return false; }
*/
- private final ThreadLocal<ReadWrite> txnMode = ThreadLocal.withInitial( ()->null ) ;
+ private ThreadLocal<Boolean> inTransaction = ThreadLocal.withInitial(() -> Boolean.FALSE);
+ private ThreadLocal<TxnType> txnType = ThreadLocal.withInitial(() -> null);
+ private ThreadLocal<ReadWrite> txnMode = ThreadLocal.withInitial(() -> null);
private final Lock lock ;
/** Create a Transactional using the given lock */
@@ -101,16 +111,24 @@ public class TransactionalLock implements Transactional {
}
ReadWrite readWrite = TxnType.convert(txnType);
boolean isRead = readWrite.equals(ReadWrite.READ) ;
- lock.enterCriticalSection(isRead) ;
- txnMode.set(readWrite) ;
+ lock.enterCriticalSection(isRead);
+ txnMode.set(readWrite);
+ }
+
+ @Override public ReadWrite transactionMode() {
+ return Lib.readThreadLocal(txnMode) ;
}
+ @Override public TxnType transactionType() {
+ return Lib.readThreadLocal(txnType) ;
+ }
+
// Lock propmotion required (Ok for mutex)
-// @Override
-// public boolean promote() {
-// return ??;
-// }
+ @Override
+ public boolean promote() {
+ return false;
+ }
@Override
public void commit() {
@@ -130,11 +148,7 @@ public class TransactionalLock implements Transactional {
}
public boolean isTransactionType(ReadWrite mode) {
- return Objects.equals(mode, txnMode.get()) ;
- }
-
- private ReadWrite getTransactionType(ReadWrite mode) {
- return txnMode.get() ;
+ return Lib.readThreadLocal(txnMode) == mode;
}
@Override
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalMutex.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalMutex.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalMutex.java
deleted file mode 100644
index 4f722c7..0000000
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalMutex.java
+++ /dev/null
@@ -1,75 +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.sparql.core;
-
-import org.apache.jena.query.ReadWrite ;
-import org.apache.jena.query.TxnType;
-import org.apache.jena.shared.Lock ;
-
-/** Transactional by mutual exclusion. */
-public class TransactionalMutex implements Transactional
-{
- private final Lock lock;
- private ThreadLocal<Boolean> isInTransaction = ThreadLocal.withInitial(()->false) ;
-
- private TransactionalMutex(Lock lock) {
- this.lock = lock ;
- }
-
- @Override
- public void begin(ReadWrite readWrite) {
- begin(TxnType.convert(readWrite));
- }
-
- @Override
- public void begin(TxnType txnType) {
- lock.enterCriticalSection(false); // Always take a write lock - i.e. exclusive.
- isInTransaction.set(true);
- }
-
- @Override
- public boolean promote() {
- return true;
- }
-
- @Override
- public void commit() {
- end() ;
- }
-
- @Override
- public void abort() {
- end() ;
- }
-
- @Override
- public boolean isInTransaction() {
- return isInTransaction == null ? false : isInTransaction.get() ;
- }
-
- @Override
- public void end() {
- if ( isInTransaction() ) {
- isInTransaction.set(false);
- lock.leaveCriticalSection();
- }
- isInTransaction.remove();
- isInTransaction = null;
- }
-}
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupported.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupported.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupported.java
index 287aabd..f2ef1a0 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupported.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupported.java
@@ -39,15 +39,21 @@ public class TransactionalNotSupported implements Transactional
// As an included component.
/*
private final Transactional txn = new TransactionalNotSupported() ;
- @Override public void begin(TxnType txnType) { txn.begin(type) ; }
- @Override public void begin(ReadWrite mode) { txn.begin(mode) ; }
- @Override public boolean promote() { returntxn.promote() ; }
- @Override public void commit() { txn.commit() ; }
- @Override public void abort() { txn.abort() ; }
- @Override public boolean isInTransaction() { return txn.isInTransaction() ; }
+ @Override public void begin() { txn.begin(); }
+ @Override public void begin(TxnType txnType) { txn.begin(txnType); }
+ @Override public void begin(ReadWrite mode) { txn.begin(mode); }
+ @Override public boolean promote() { return txn.promote(); }
+ @Override public void commit() { txn.commit(); }
+ @Override public void abort() { txn.abort(); }
+ @Override public boolean isInTransaction() { return txn.isInTransaction(); }
@Override public void end() { txn.end(); }
- @Override public boolean supportsTransactions() { return true ; }
- @Override public boolean supportsTransactionAbort() { return false ; }
+ @Override public ReadWrite transactionMode() { return txn.transactionMode(); }
+ @Override public TxnType transactionType() { return txn.transactionType(); }
+
+ For DatasetGraphs:
+
+ @Override public boolean supportsTransactions() { return true; }
+ @Override public boolean supportsTransactionAbort() { return false; }
*/
@Override
@@ -76,6 +82,13 @@ public class TransactionalNotSupported implements Transactional
@Override
public boolean isInTransaction()
{ return false ; }
+
+ @Override public ReadWrite transactionMode()
+ { throw new UnsupportedOperationException("Transactional.transactionMode") ; }
+
+ @Override public TxnType transactionType()
+ { throw new UnsupportedOperationException("Transactional.transactionType") ; }
+
@Override
public void end()
@@ -85,9 +98,6 @@ public class TransactionalNotSupported implements Transactional
return false ;
}
- /** Declare whether {@link #abort} is supported.
- * This goes along with clearing up after exceptions inside application transaction code.
- */
public boolean supportsTransactionAbort() {
return false;
}
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupportedMixin.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupportedMixin.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupportedMixin.java
index 4a98044..98fd2e9 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupportedMixin.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNotSupportedMixin.java
@@ -20,11 +20,9 @@ package org.apache.jena.sparql.core;
import org.apache.jena.query.ReadWrite ;
import org.apache.jena.query.TxnType;
-import org.apache.jena.shared.LockMutex ;
/** Mixin interface for the "un-Transactional" interface.
- * Use with {@link LockMutex}.
- * @see TransactionalNotSupportedMixin
+ * @see TransactionalNotSupported
*/
public interface TransactionalNotSupportedMixin extends Transactional
{
@@ -52,12 +50,19 @@ public interface TransactionalNotSupportedMixin extends Transactional
{ throw new UnsupportedOperationException("Transactional.abort") ; }
@Override
+ public default void end()
+ { throw new UnsupportedOperationException("Transactional.end") ; }
+
+ @Override
public default boolean isInTransaction()
{ return false ; }
+
+ @Override default public ReadWrite transactionMode()
+ { throw new UnsupportedOperationException("Transactional.transactionMode") ; }
+
+ @Override default public TxnType transactionType()
+ { throw new UnsupportedOperationException("Transactional.transactionType") ; }
- @Override
- public default void end()
- { throw new UnsupportedOperationException("Transactional.end") ; }
public default boolean supportsTransactions()
{ return false ; }
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNull.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNull.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNull.java
index 822b77d..4b5ecf8 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNull.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/TransactionalNull.java
@@ -28,25 +28,56 @@ import org.apache.jena.sparql.JenaTransactionException;
* It does provide "abort".
*/
public class TransactionalNull implements Transactional {
+ /*
+ @Override public void begin() { txn.begin(); }
+ @Override public void begin(TxnType txnType) { txn.begin(txnType); }
+ @Override public void begin(ReadWrite mode) { txn.begin(mode); }
+ @Override public boolean promote() { return txn.promote(); }
+ @Override public void commit() { txn.commit(); }
+ @Override public void abort() { txn.abort(); }
+ @Override public boolean isInTransaction() { return txn.isInTransaction(); }
+ @Override public void end() { txn.end(); }
+ @Override public ReadWrite transactionMode() { return txn.transactionMode(); }
+ @Override public TxnType transactionType() { return txn.transactionType(); }
+
+ For DatasetGraphs:
+
+ @Override public boolean supportsTransactions() { return true; }
+ @Override public boolean supportsTransactionAbort() { return false; }
+ */
+
public static TransactionalNull create() { return new TransactionalNull(); }
private ThreadLocal<Boolean> inTransaction = ThreadLocal.withInitial(() -> Boolean.FALSE);
+ private ThreadLocal<TxnType> txnType = ThreadLocal.withInitial(() -> null);
+ private ThreadLocal<ReadWrite> txnMode = ThreadLocal.withInitial(() -> null);
+ @Override
+ public ReadWrite transactionMode() {
+ return txnMode.get();
+ }
+
+ @Override
+ public void begin(ReadWrite readWrite) {
+ begin(TxnType.convert(readWrite));
+ }
@Override
public void begin(TxnType type) {
if ( inTransaction.get() )
throw new JenaTransactionException("Already in transaction");
inTransaction.set(true);
+ txnType.set(type);
+ txnMode.set(TxnType.initial(type));
}
@Override
- public void begin(ReadWrite readWrite) {
- begin(TxnType.convert(readWrite));
+ public boolean promote() {
+ if ( ! inTransaction.get() )
+ throw new JenaTransactionException("Not in transaction");
+ txnMode.set(ReadWrite.WRITE);
+ return true;
}
-
- @Override
- public boolean promote() { return true; }
@Override
public void commit() {
@@ -69,14 +100,16 @@ public class TransactionalNull implements Transactional {
@Override
public void end() {
- inTransaction.set(false);
+ clearup();
}
-// @Override
-// public boolean promote() {
-// return true;
-// }
-
+ private void clearup() {
+ inTransaction.set(false);
+ inTransaction.remove();
+ txnType.set(null);
+ txnType.remove();
+ }
+
public void remove() {
inTransaction.remove();
}
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/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 1905d05..44dd8db 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
@@ -101,7 +101,7 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
return transactionType.get();
}
- private void transactionType(final ReadWrite readWrite) {
+ private void transactionMode(final ReadWrite readWrite) {
transactionMode.set(readWrite);
}
@@ -139,24 +139,21 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
public boolean supportsTransactionAbort() { return true; }
@Override
+ public void begin(final ReadWrite readWrite) {
+ begin(TxnType.convert(readWrite));
+ }
+
+ @Override
public void begin(TxnType txnType) {
if (isInTransaction())
throw new JenaTransactionException("Transactions cannot be nested!");
transactionType.set(txnType);
- ReadWrite initial = txnType.equals(TxnType.WRITE) ? WRITE : READ;
- _begin(initial);
+ _begin(txnType, TxnType.initial(txnType));
}
- @Override
- public void begin(final ReadWrite readWrite) {
- if (isInTransaction())
- throw new JenaTransactionException("Transactions cannot be nested!");
- transactionType.set(TxnType.convert(readWrite));
- _begin(readWrite) ;
- }
-
- private void _begin(ReadWrite readWrite) {
- startTransaction(readWrite);
+ private void _begin(TxnType txnType, ReadWrite readWrite) {
+ // Takes transactionLock
+ startTransaction(txnType, readWrite);
withLock(systemLock, () ->{
quadsIndex().begin(readWrite);
defaultGraph().begin(readWrite);
@@ -165,9 +162,10 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
}
/** Called transaction start code at most once per transaction. */
- private void startTransaction(ReadWrite mode) {
+ private void startTransaction(TxnType txnType, ReadWrite mode) {
transactionLock.enterCriticalSection(mode.equals(ReadWrite.READ)); // get the dataset write lock, if needed.
- transactionType(mode);
+ transactionType.set(txnType);
+ transactionMode(mode);
isInTransaction(true);
}
@@ -193,7 +191,7 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
case WRITE :
return true;
case READ :
- return false ;
+ throw new JenaTransactionException("Tried to promote READ transaction");
case READ_COMMITTED_PROMOTE :
readCommitted = true;
case READ_PROMOTE :
@@ -204,9 +202,6 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
throw new NullPointerException();
}
- // XXX Check "mutate".
- mutate(null, null);
-
try {
_promote(readCommitted);
return true;
@@ -215,10 +210,6 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
}
}
- /*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()) ;
@@ -240,8 +231,8 @@ public class DatasetGraphInMemory extends DatasetGraphTriplesQuads implements Tr
throw new JenaTransactionException("Concurrent writer changed the dataset : can't promote") ;
}
// We have the lock and we have promoted!
- transactionType(WRITE);
- _begin(WRITE) ;
+ transactionMode(WRITE);
+ _begin(transactionType(), ReadWrite.WRITE) ;
}
@Override
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/main/java/org/apache/jena/system/TxnCounter.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/main/java/org/apache/jena/system/TxnCounter.java b/jena-arq/src/main/java/org/apache/jena/system/TxnCounter.java
index 6e93dcd..e641d55 100644
--- a/jena-arq/src/main/java/org/apache/jena/system/TxnCounter.java
+++ b/jena-arq/src/main/java/org/apache/jena/system/TxnCounter.java
@@ -18,15 +18,14 @@
package org.apache.jena.system;
-import static org.apache.jena.query.ReadWrite.WRITE ;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.Semaphore ;
-import java.util.concurrent.atomic.AtomicLong ;
-
-import org.apache.jena.atlas.lib.Lib ;
-import org.apache.jena.query.ReadWrite ;
-import org.apache.jena.sparql.JenaTransactionException ;
-import org.apache.jena.sparql.core.Transactional ;
+import org.apache.jena.atlas.lib.Lib;
+import org.apache.jena.query.ReadWrite;
+import org.apache.jena.query.TxnType;
+import org.apache.jena.sparql.JenaTransactionException;
+import org.apache.jena.sparql.core.Transactional;
/** A MR+SW transactional Counter */
public class TxnCounter implements Transactional {
@@ -35,148 +34,198 @@ public class TxnCounter implements Transactional {
// Semaphore to implement "Single Active Writer" - independent of readers
// This is not reentrant.
- private Semaphore writersWaiting = new Semaphore(1, true) ;
+ private Semaphore writersWaiting = new Semaphore(1, true);
private void releaseWriterLock() {
- int x = writersWaiting.availablePermits() ;
+ int x = writersWaiting.availablePermits();
if ( x != 0 )
- throw new JenaTransactionException("TransactionCoordinator: Probably mismatch of enable/disableWriter calls") ;
- writersWaiting.release() ;
+ throw new JenaTransactionException("TransactionCoordinator: Probably mismatch of enable/disableWriter calls");
+ writersWaiting.release();
}
private boolean acquireWriterLock(boolean canBlock) {
if ( ! canBlock )
- return writersWaiting.tryAcquire() ;
+ return writersWaiting.tryAcquire();
try {
- writersWaiting.acquire() ;
+ writersWaiting.acquire();
return true;
- } catch (InterruptedException e) { throw new JenaTransactionException(e) ; }
+ } catch (InterruptedException e) { throw new JenaTransactionException(e); }
}
// ---- TransactionCoordinator.
// Transaction state.
static class IntegerState {
- long txnValue ;
- public IntegerState(long v) { this.txnValue = v ; }
+ long txnValue;
+ public IntegerState(long v) { this.txnValue = v; }
}
// Global state - the exterally visible value and the starting point for any
// transaction. This is set to a new value when a write transaction commits.
- private final AtomicLong value = new AtomicLong(-1712) ;
+ private final AtomicLong value = new AtomicLong(-1712);
+ private final AtomicLong epoch = new AtomicLong(1);
// ---- Transaction state.
// The per-transaction state (inside a transaction). Null outside a transaction
// cleared by commit or abort in a write transaction.
- private ThreadLocal<IntegerState> txnValue = ThreadLocal.withInitial(()->null) ;
+ private ThreadLocal<IntegerState> transactionValue = ThreadLocal.withInitial(()->null);
// The kind of transaction.
- private ThreadLocal<ReadWrite> txnMode = ThreadLocal.withInitial(()->null) ;
+ private ThreadLocal<ReadWrite> transactionMode = ThreadLocal.withInitial(()->null);
+ private ThreadLocal<TxnType> transactionType = ThreadLocal.withInitial(()->null);
+ private ThreadLocal<Long> transactionEpoch = ThreadLocal.withInitial(()->null);
- // Syncrhonization for making changes.
- private Object txnLifecycleLock = new Object() ;
+ // Synchronization for making changes.
+ private Object txnLifecycleLock = new Object();
public TxnCounter(long x) {
- value.set(x) ;
+ value.set(x);
}
@Override
public void begin(ReadWrite readWrite) {
- begin(readWrite, true) ;
+ begin(TxnType.convert(readWrite));
+ }
+
+ @Override
+ public void begin(TxnType txnType) {
+ begin(txnType, true);
}
- public void begin(ReadWrite readWrite, boolean canBlock) {
+ public void begin(TxnType txnType, boolean canBlock) {
// Ensure a single writer.
// (Readers never block at this point.)
- if ( readWrite == WRITE ) {
+ if ( txnType == TxnType.WRITE ) {
// Writers take a WRITE permit from the semaphore to ensure there
// is at most one active writer, else the attempt to start the
// transaction blocks.
// Released by in commit/abort.
- acquireWriterLock(canBlock) ;
+ acquireWriterLock(canBlock);
}
// at this point,
// One writer or one of many readers.
synchronized(txnLifecycleLock) {
- if ( txnMode.get() != null )
- throw new JenaTransactionException("Already in a transaction") ;
- IntegerState state = new IntegerState(value.get()) ;
- txnValue.set(state) ;
- txnMode.set(readWrite);
+ if ( transactionMode.get() != null )
+ throw new JenaTransactionException("Already in a transaction");
+ long thisEpoch = epoch.incrementAndGet();
+ transactionEpoch.set(thisEpoch) ;
+ IntegerState state = new IntegerState(value.get());
+ transactionValue.set(state);
+ transactionMode.set(TxnType.initial(txnType));
+ transactionType.set(txnType);
}
}
@Override
+ public boolean promote() {
+ checkTxn();
+ if ( transactionMode.get() == ReadWrite.WRITE )
+ return true;
+ TxnType txnType = transactionType.get();
+ if ( txnType == TxnType.READ )
+ throw new JenaTransactionException("Attempt to promote a READ transsction");
+ if ( txnType == TxnType.READ_COMMITTED_PROMOTE ) {
+ acquireWriterLock(true);
+ transactionMode.set(ReadWrite.WRITE);
+ IntegerState state = new IntegerState(value.get());
+ transactionValue.set(state);
+ return true;
+ }
+ // READ no committed.
+ acquireWriterLock(true);
+ synchronized(txnLifecycleLock) {
+ long nowEpoch = epoch.get();
+ if ( transactionEpoch.get() != nowEpoch ) {
+ // Can't.
+ releaseWriterLock();
+ return false;
+ }
+ // Can.
+ transactionMode.set(ReadWrite.WRITE);
+ }
+ return true;
+ }
+
+
+ @Override
public void commit() {
checkTxn();
if ( isWriteTxn() ) {
// Set global.
- value.set(getDataState().txnValue) ;
- txnValue.set(null);
+ value.set(getDataState().txnValue);
+ transactionValue.set(null);
releaseWriterLock();
}
- endOnce() ;
+ endOnce();
}
@Override
public void abort() {
checkTxn();
if ( isWriteTxn() ) {
- txnValue.set(null);
+ transactionValue.set(null);
releaseWriterLock();
}
- endOnce() ;
+ endOnce();
}
@Override
public boolean isInTransaction() {
- ReadWrite mode = txnMode.get() ;
- if ( mode == null )
- // Remove it - avoid holding the memory.
- txnMode.remove();
- return mode != null ;
+ return Lib.readThreadLocal(transactionMode) != null;
+ }
+
+ @Override
+ public ReadWrite transactionMode() {
+ return Lib.readThreadLocal(transactionMode);
+ }
+
+ @Override
+ public TxnType transactionType() {
+ return Lib.readThreadLocal(transactionType);
}
@Override
public void end() {
if ( ! isInTransaction() )
- return ;
- if ( isWriteTxn() && txnValue.get() != null )
- throw new JenaTransactionException("No commit or abort before end for a write transaction") ;
- endOnce() ;
+ return;
+ if ( isWriteTxn() && transactionValue.get() != null )
+ throw new JenaTransactionException("No commit or abort before end for a write transaction");
+ endOnce();
}
private void endOnce() {
if ( isActiveTxn() ) {
synchronized(txnLifecycleLock) {
- txnValue.remove();
- txnMode.remove();
+ transactionValue.remove();
+ transactionType.remove();
+ transactionMode.remove();
+ transactionEpoch.remove();
}
}
}
/** Increment the value inside a write transaction */
public void inc() {
- checkWriteTxn() ;
- IntegerState ts = getDataState() ;
- ts.txnValue++ ;
+ checkWriteTxn();
+ IntegerState ts = getDataState();
+ ts.txnValue++;
}
/** Decrement the value inside a write transaction */
public void dec() {
- checkWriteTxn() ;
- IntegerState ts = getDataState() ;
- ts.txnValue-- ;
+ checkWriteTxn();
+ IntegerState ts = getDataState();
+ ts.txnValue--;
}
/** Set the value inside a write transaction, return the old value*/
public long set(long x) {
- checkWriteTxn() ;
- IntegerState ts = getDataState() ;
- long v = ts.txnValue ;
- ts.txnValue = x ;
- return v ;
+ checkWriteTxn();
+ IntegerState ts = getDataState();
+ long v = ts.txnValue;
+ ts.txnValue = x;
+ return v;
}
@@ -186,7 +235,7 @@ public class TxnCounter implements Transactional {
*/
public long read() {
checkTxn();
- return getDataState().txnValue ;
+ return getDataState().txnValue;
}
/** Return the current value.
@@ -197,14 +246,14 @@ public class TxnCounter implements Transactional {
*/
public long get() {
if ( isActiveTxn() )
- return getDataState().txnValue ;
+ return getDataState().txnValue;
else
- return value.get() ;
+ return value.get();
}
/** Read the current global state (that is, the last committed value) outside a transaction. */
public long value() {
- return value.get() ;
+ return value.get();
}
// These two operations not clear the thread local if we are not in a transaction.
@@ -213,28 +262,28 @@ public class TxnCounter implements Transactional {
/** Is this a write transaction? Should be called inside a transaction. */
private boolean isWriteTxn() {
- ReadWrite rw = txnMode.get() ;
+ ReadWrite rw = transactionMode.get();
if ( rw == null )
- throw new JenaTransactionException(Lib.classShortName(this.getClass())+".isWriteTxn called outside a transaction") ;
- return txnMode.get() == ReadWrite.WRITE ;
+ throw new JenaTransactionException(Lib.classShortName(this.getClass())+".isWriteTxn called outside a transaction");
+ return transactionMode.get() == ReadWrite.WRITE;
}
private boolean isActiveTxn() {
- ReadWrite rw = txnMode.get() ;
- return rw != null ;
+ ReadWrite rw = transactionMode.get();
+ return rw != null;
}
private IntegerState getDataState() {
- return txnValue.get() ;
+ return transactionValue.get();
}
private void checkWriteTxn() {
if ( ! isWriteTxn() )
- throw new JenaTransactionException("Not in a write transaction") ;
+ throw new JenaTransactionException("Not in a write transaction");
}
private void checkTxn() {
if ( ! isActiveTxn() )
- throw new JenaTransactionException("Not in a transaction") ;
+ throw new JenaTransactionException("Not in a transaction");
}
}
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/test/java/org/apache/jena/sparql/core/TS_Core.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/core/TS_Core.java b/jena-arq/src/test/java/org/apache/jena/sparql/core/TS_Core.java
index c851ee8..800e428 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/core/TS_Core.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/core/TS_Core.java
@@ -34,7 +34,6 @@ import org.junit.runners.Suite ;
, TestDatasetGraphViewGraphs.class
, TestGraphView.class
, TestDatasetMonitor.class
- , TestDatasetGraphWithLock.class
, TestDatasetGraphBaseFind_General.class
, TestDatasetGraphBaseFind_General.class
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/test/java/org/apache/jena/sparql/core/TestDatasetGraphWithLock.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/core/TestDatasetGraphWithLock.java b/jena-arq/src/test/java/org/apache/jena/sparql/core/TestDatasetGraphWithLock.java
deleted file mode 100644
index 0a3b0a6..0000000
--- a/jena-arq/src/test/java/org/apache/jena/sparql/core/TestDatasetGraphWithLock.java
+++ /dev/null
@@ -1,30 +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.sparql.core;
-
-import org.apache.jena.query.Dataset ;
-import org.apache.jena.query.DatasetFactory ;
-
-/** Non-transaction part of DatasetGraphWithLock testing */
-public class TestDatasetGraphWithLock extends AbstractTestDataset {
- @Override
- protected Dataset createDataset() {
- return DatasetFactory.wrap(new DatasetGraphWithLock(DatasetGraphFactory.create()));
- }
-}
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryLock.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryLock.java b/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryLock.java
index 27daed4..721dbb9 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryLock.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/core/mem/TestDatasetGraphInMemoryLock.java
@@ -20,9 +20,9 @@ package org.apache.jena.sparql.core.mem;
import org.apache.jena.query.Dataset ;
import org.apache.jena.query.DatasetFactory ;
-import org.apache.jena.sparql.core.TestDatasetGraphWithLock ;
+import org.apache.jena.sparql.core.AbstractTestDataset;
-public class TestDatasetGraphInMemoryLock extends TestDatasetGraphWithLock {
+public class TestDatasetGraphInMemoryLock extends AbstractTestDataset {
@Override
protected Dataset createDataset() {
return DatasetFactory.createTxnMem();
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/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 3378a87..9134668 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
@@ -18,7 +18,7 @@
package org.apache.jena.sparql.transaction ;
-import static org.junit.Assert.assertEquals ;
+import static org.junit.Assert.* ;
import static org.junit.Assert.fail ;
import java.util.concurrent.* ;
@@ -172,7 +172,7 @@ public abstract class AbstractTestTransPromote {
assertCount(0, dsg) ;
}
- // XXX LOCK UP
+ // LOCK UP
//@Test public void promote_snapshot_06() { run_06(TxnMode.READ_PROMOTE) ; }
//@Test public void promote_readCommitted_06() { run_06(TxnMode.READ_COMMITTED_PROMOTE) ; }
@@ -387,4 +387,51 @@ public abstract class AbstractTestTransPromote {
throw e ;
} catch (InterruptedException | ExecutionException e1) { throw new RuntimeException(e1) ; }
}
+
+ // This would locks up because of a WRITE-WRITE deadly embrace.
+ // @Test(expected=JenaTransactionException.class)
+ // public void promote11() { test2(TxnMode.WRITE); }
+
+ @Test
+ public void promote_thread_writer_1() { test_thread_writer(TxnType.READ_COMMITTED_PROMOTE); }
+
+ @Test(expected=JenaTransactionException.class)
+ public void promote_thread_writer_2() { test_thread_writer(TxnType.READ_PROMOTE); }
+
+ private void test_thread_writer(TxnType txnType) {
+ DatasetGraph dsg = create();
+ ThreadAction a = ThreadTxn.threadTxnWrite(dsg, ()->dsg.add(q1));
+ dsg.begin(txnType);
+ assertEquals(txnType, dsg.transactionType());
+ a.run();
+ dsg.add(q2);
+ // TDB1 does not keep the the original TxnType.
+ assertEquals(txnType, dsg.transactionType());
+ assertEquals(ReadWrite.WRITE, dsg.transactionMode());
+ dsg.commit();
+ dsg.end();
+ }
+
+ // With explicit "promote()"
+ private void test_promote_thread_writer(TxnType txnType) {
+ DatasetGraph dsg = create();
+ ThreadAction a = ThreadTxn.threadTxnWrite(dsg, ()->dsg.add(q1));
+ dsg.begin(txnType);
+ assertEquals(txnType, dsg.transactionType());
+ a.run();
+
+ boolean b = dsg.promote();
+
+ if ( txnType == TxnType.READ_PROMOTE )
+ assertFalse(b);
+ if ( txnType == TxnType.READ_COMMITTED_PROMOTE )
+ assertTrue(b);
+
+ dsg.add(q2);
+ assertEquals(txnType, dsg.transactionType());
+ assertEquals(ReadWrite.WRITE, dsg.transactionMode());
+ dsg.commit();
+ dsg.end();
+ }
+
}
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/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 32b8ca3..c1043b8 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
@@ -18,8 +18,9 @@
package org.apache.jena.sparql.transaction;
-import static org.apache.jena.query.ReadWrite.READ ;
-import static org.apache.jena.query.ReadWrite.WRITE ;
+import static org.apache.jena.query.TxnType.READ ;
+import static org.apache.jena.query.TxnType.WRITE ;
+import static org.junit.Assume.assumeTrue;
import java.util.ArrayList ;
import java.util.List ;
@@ -30,15 +31,20 @@ import org.apache.jena.atlas.junit.BaseTest ;
import org.apache.jena.atlas.lib.Lib ;
import org.apache.jena.query.Dataset ;
import org.apache.jena.query.ReadWrite ;
+import org.apache.jena.query.TxnType;
+import org.apache.jena.shared.JenaException;
import org.apache.jena.sparql.JenaTransactionException ;
-import static org.junit.Assume.* ;
import org.junit.Test ;
+/**
+ * Dataset transaction lifecycle.
+ */
public abstract class AbstractTestTransactionLifecycle extends BaseTest
{
protected abstract Dataset create() ;
- protected boolean supportsAbort() { return true ; }
+ protected boolean supportsAbort() { return true ; }
+ protected boolean supportsPromote() { return true ; }
@Test
public void transaction_00() {
@@ -49,7 +55,7 @@ public abstract class AbstractTestTransactionLifecycle extends BaseTest
@Test
public void transaction_r01() {
Dataset ds = create() ;
- ds.begin(ReadWrite.READ) ;
+ ds.begin(TxnType.READ) ;
assertTrue(ds.isInTransaction()) ;
ds.end() ;
assertFalse(ds.isInTransaction()) ;
@@ -58,7 +64,7 @@ public abstract class AbstractTestTransactionLifecycle extends BaseTest
@Test
public void transaction_r02() {
Dataset ds = create() ;
- ds.begin(ReadWrite.READ) ;
+ ds.begin(TxnType.READ) ;
assertTrue(ds.isInTransaction()) ;
ds.commit() ;
assertFalse(ds.isInTransaction()) ;
@@ -69,7 +75,7 @@ public abstract class AbstractTestTransactionLifecycle extends BaseTest
@Test
public void transaction_r03() {
Dataset ds = create() ;
- ds.begin(ReadWrite.READ) ;
+ ds.begin(TxnType.READ) ;
assertTrue(ds.isInTransaction()) ;
ds.abort() ;
assertFalse(ds.isInTransaction()) ;
@@ -78,8 +84,26 @@ public abstract class AbstractTestTransactionLifecycle extends BaseTest
}
@Test
+ public void transaction_r04() {
+ Dataset ds = create() ;
+ ds.begin(ReadWrite.READ) ;
+ assertTrue(ds.isInTransaction()) ;
+ ds.end() ;
+ assertFalse(ds.isInTransaction()) ;
+ }
+
+ @Test
public void transaction_w01() {
Dataset ds = create() ;
+ ds.begin(TxnType.WRITE) ;
+ assertTrue(ds.isInTransaction()) ;
+ ds.commit() ;
+ assertFalse(ds.isInTransaction()) ;
+ }
+
+ @Test
+ public void transaction_w02() {
+ Dataset ds = create() ;
ds.begin(ReadWrite.WRITE) ;
assertTrue(ds.isInTransaction()) ;
ds.commit() ;
@@ -87,19 +111,19 @@ public abstract class AbstractTestTransactionLifecycle extends BaseTest
}
@Test
- public void transaction_w02() {
+ public void transaction_w03() {
assumeTrue(supportsAbort()) ;
Dataset ds = create() ;
- ds.begin(ReadWrite.WRITE) ;
+ ds.begin(TxnType.WRITE) ;
assertTrue(ds.isInTransaction()) ;
ds.abort() ;
assertFalse(ds.isInTransaction()) ;
}
@Test
- public void transaction_w03() {
+ public void transaction_w04() {
Dataset ds = create() ;
- ds.begin(ReadWrite.WRITE) ;
+ ds.begin(TxnType.WRITE) ;
assertTrue(ds.isInTransaction()) ;
ds.commit() ;
assertFalse(ds.isInTransaction()) ;
@@ -108,10 +132,10 @@ public abstract class AbstractTestTransactionLifecycle extends BaseTest
}
@Test
- public void transaction_w04() {
+ public void transaction_w05() {
assumeTrue(supportsAbort()) ;
Dataset ds = create() ;
- ds.begin(ReadWrite.WRITE) ;
+ ds.begin(TxnType.WRITE) ;
assertTrue(ds.isInTransaction()) ;
ds.abort() ;
assertFalse(ds.isInTransaction()) ;
@@ -120,21 +144,110 @@ public abstract class AbstractTestTransactionLifecycle extends BaseTest
}
@Test
- public void transaction_w05() {
+ public void transaction_w06() {
assumeTrue(supportsAbort()) ;
// .end is not necessary
Dataset ds = create() ;
- ds.begin(ReadWrite.WRITE) ;
+ ds.begin(TxnType.WRITE) ;
assertTrue(ds.isInTransaction()) ;
ds.abort() ;
assertFalse(ds.isInTransaction()) ;
- ds.begin(ReadWrite.WRITE) ;
+ ds.begin(TxnType.WRITE) ;
assertTrue(ds.isInTransaction()) ;
ds.abort() ;
assertFalse(ds.isInTransaction()) ;
}
+// TxnType.READ_PROMOTE
+// TxnType.READ_COMMITTED_PROMOTE
+
+ @Test
+ public void transaction_p01() {
+ assumeTrue(supportsPromote()) ;
+ Dataset ds = create() ;
+ ds.begin(TxnType.READ_PROMOTE) ;
+ assertEquals(TxnType.READ_PROMOTE, ds.transactionType());
+ assertTrue(ds.isInTransaction()) ;
+ assertEquals(ReadWrite.READ, ds.transactionMode());
+ ds.promote();
+ assertEquals(ReadWrite.WRITE, ds.transactionMode());
+ ds.commit();
+ ds.end();
+ }
+
+ @Test
+ public void transaction_p02() {
+ assumeTrue(supportsPromote()) ;
+ Dataset ds = create() ;
+ ds.begin(TxnType.READ_COMMITTED_PROMOTE) ;
+ assertEquals(TxnType.READ_COMMITTED_PROMOTE, ds.transactionType());
+ assertTrue(ds.isInTransaction()) ;
+ assertEquals(ReadWrite.READ, ds.transactionMode());
+ boolean b = ds.promote();
+ assertTrue(b) ;
+ assertEquals(ReadWrite.WRITE, ds.transactionMode());
+ ds.commit();
+ ds.end();
+ }
+
+ @Test
+ public void transaction_p03() {
+ assumeTrue(supportsPromote()) ;
+ Dataset ds = create() ;
+ ds.begin(TxnType.READ_PROMOTE) ;
+ assertTrue(ds.isInTransaction()) ;
+ assertEquals(ReadWrite.READ, ds.transactionMode());
+ boolean b = ds.promote();
+ assertTrue(b) ;
+ assertEquals(ReadWrite.WRITE, ds.transactionMode());
+ ds.abort();
+ ds.end();
+ assertFalse(ds.isInTransaction()) ;
+ }
+
+ @Test
+ public void transaction_p04() {
+ assumeTrue(supportsPromote()) ;
+ Dataset ds = create() ;
+ ds.begin(TxnType.READ_COMMITTED_PROMOTE) ;
+ assertTrue(ds.isInTransaction()) ;
+ assertEquals(ReadWrite.READ, ds.transactionMode());
+ boolean b = ds.promote();
+ assertTrue(b) ;
+ assertEquals(ReadWrite.WRITE, ds.transactionMode());
+ ds.abort();
+ ds.end();
+ assertFalse(ds.isInTransaction()) ;
+ }
+
+ @Test
+ public void transaction_p05() {
+ assumeTrue(supportsPromote()) ;
+ Dataset ds = create() ;
+ ds.begin(TxnType.READ_COMMITTED_PROMOTE) ;
+ assertTrue(ds.isInTransaction()) ;
+ boolean b1 = ds.promote();
+ assertTrue(b1) ;
+ boolean b2 = ds.promote();
+ assertTrue(b2) ;
+ ds.commit();
+ ds.end();
+ }
+
+ @Test(expected=JenaException.class)
+ public void transaction_err_read_promote() {
+ assumeTrue(supportsPromote()) ;
+ Dataset ds = create() ;
+ ds.begin(TxnType.READ) ;
+ boolean b = ds.promote(); // Illgeal.
+ assertFalse(b) ;
+ ds.commit();
+ ds.end();
+ }
+
+ // XXX READ_PROMOTE -> update -> fail promote/boolean.
+
// Patterns.
@Test
public void transaction_pattern_01() {
@@ -253,7 +366,7 @@ public abstract class AbstractTestTransactionLifecycle extends BaseTest
public void transaction_err_12() { testAbortCommit(WRITE) ; }
private void read1(Dataset ds) {
- ds.begin(ReadWrite.READ) ;
+ ds.begin(TxnType.READ) ;
assertTrue(ds.isInTransaction()) ;
ds.commit() ;
assertFalse(ds.isInTransaction()) ;
@@ -261,14 +374,14 @@ public abstract class AbstractTestTransactionLifecycle extends BaseTest
}
private void read2(Dataset ds) {
- ds.begin(ReadWrite.READ) ;
+ ds.begin(TxnType.READ) ;
assertTrue(ds.isInTransaction()) ;
ds.end() ;
assertFalse(ds.isInTransaction()) ;
}
private void write(Dataset ds) {
- ds.begin(ReadWrite.WRITE) ;
+ ds.begin(TxnType.WRITE) ;
assertTrue(ds.isInTransaction()) ;
ds.commit() ;
assertFalse(ds.isInTransaction()) ;
@@ -281,67 +394,67 @@ public abstract class AbstractTestTransactionLifecycle extends BaseTest
// Error conditions that should be detected.
- private void testBeginBegin(ReadWrite mode1, ReadWrite mode2) {
+ private void testBeginBegin(TxnType txnType1, TxnType txnType2) {
Dataset ds = create() ;
- ds.begin(mode1) ;
+ ds.begin(txnType1) ;
try {
- ds.begin(mode2) ;
- fail("Expected transaction exception - begin-begin (" + mode1 + ", " + mode2 + ")") ;
+ ds.begin(txnType2) ;
+ fail("Expected transaction exception - begin-begin (" + txnType1 + ", " + txnType2 + ")") ;
}
catch (JenaTransactionException ex) {
safeEnd(ds) ;
}
}
- private void testCommitCommit(ReadWrite mode) {
+ private void testCommitCommit(TxnType txnType) {
Dataset ds = create() ;
- ds.begin(mode) ;
+ ds.begin(txnType) ;
ds.commit() ;
try {
ds.commit() ;
- fail("Expected transaction exception - commit-commit(" + mode + ")") ;
+ fail("Expected transaction exception - commit-commit(" + txnType + ")") ;
}
catch (JenaTransactionException ex) {
safeEnd(ds) ;
}
}
- private void testCommitAbort(ReadWrite mode) {
+ private void testCommitAbort(TxnType txnType) {
assumeTrue(supportsAbort()) ;
Dataset ds = create() ;
- ds.begin(mode) ;
+ ds.begin(txnType) ;
ds.commit() ;
try {
ds.abort() ;
- fail("Expected transaction exception - commit-abort(" + mode + ")") ;
+ fail("Expected transaction exception - commit-abort(" + txnType + ")") ;
}
catch (JenaTransactionException ex) {
safeEnd(ds) ;
}
}
- private void testAbortAbort(ReadWrite mode) {
+ private void testAbortAbort(TxnType txnType) {
assumeTrue(supportsAbort()) ;
Dataset ds = create() ;
- ds.begin(mode) ;
+ ds.begin(txnType) ;
ds.abort() ;
try {
ds.abort() ;
- fail("Expected transaction exception - abort-abort(" + mode + ")") ;
+ fail("Expected transaction exception - abort-abort(" + txnType + ")") ;
}
catch (JenaTransactionException ex) {
ds.end() ;
}
}
- private void testAbortCommit(ReadWrite mode) {
+ private void testAbortCommit(TxnType txnType) {
assumeTrue(supportsAbort()) ;
Dataset ds = create() ;
- ds.begin(mode) ;
+ ds.begin(txnType) ;
ds.abort() ;
try {
ds.commit() ;
- fail("Expected transaction exception - abort-commit(" + mode + ")") ;
+ fail("Expected transaction exception - abort-commit(" + txnType + ")") ;
}
catch (JenaTransactionException ex) {
safeEnd(ds) ;
@@ -360,7 +473,7 @@ public abstract class AbstractTestTransactionLifecycle extends BaseTest
@Override
public Boolean call() {
- ds.begin(ReadWrite.WRITE);
+ ds.begin(TxnType.WRITE);
long x = counter.incrementAndGet() ;
// Hold the lock for a short while.
// The W threads will take the sleep serially.
@@ -394,7 +507,7 @@ public abstract class AbstractTestTransactionLifecycle extends BaseTest
Callable<Boolean> callable = new Callable<Boolean>() {
@Override
public Boolean call() {
- ds.begin(ReadWrite.READ);
+ ds.begin(TxnType.READ);
long x = counter.incrementAndGet() ;
// Hold the lock for a few seconds - these should be in parallel.
Lib.sleep(1000) ;
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/test/java/org/apache/jena/sparql/transaction/TS_Transaction.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/transaction/TS_Transaction.java b/jena-arq/src/test/java/org/apache/jena/sparql/transaction/TS_Transaction.java
index 7fbbe62..7cc1879 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/transaction/TS_Transaction.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/transaction/TS_Transaction.java
@@ -25,8 +25,6 @@ import org.junit.runners.Suite.SuiteClasses ;
@RunWith(Suite.class)
@SuiteClasses( {
TestTransactionSupport.class
- , TestTransactionDSGWithLockNoAbort.class
- , TestTransactionDSGWithLockWithAbort.class
})
public class TS_Transaction
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/test/java/org/apache/jena/sparql/transaction/TestTransactionDSGWithLockNoAbort.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/transaction/TestTransactionDSGWithLockNoAbort.java b/jena-arq/src/test/java/org/apache/jena/sparql/transaction/TestTransactionDSGWithLockNoAbort.java
deleted file mode 100644
index 98617d0..0000000
--- a/jena-arq/src/test/java/org/apache/jena/sparql/transaction/TestTransactionDSGWithLockNoAbort.java
+++ /dev/null
@@ -1,41 +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.sparql.transaction;
-
-import org.apache.jena.query.Dataset ;
-import org.apache.jena.query.DatasetFactory ;
-import org.apache.jena.sparql.core.DatasetGraph ;
-import org.apache.jena.sparql.core.DatasetGraphFactory ;
-import org.apache.jena.sparql.core.DatasetGraphWithLock ;
-
-/** Version with abortImplemented == false (the default). */
-public class TestTransactionDSGWithLockNoAbort extends AbstractTestTransactionLifecycle
-{
- @Override
- protected boolean supportsAbort() { return false ; }
-
- @Override
- protected Dataset create()
- {
- DatasetGraph dsg = DatasetGraphFactory.create() ;
- DatasetGraphWithLock dsgl = new DatasetGraphWithLock(dsg, false) ;
- return DatasetFactory.wrap(dsgl) ;
- }
- }
-
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/test/java/org/apache/jena/sparql/transaction/TestTransactionDSGWithLockWithAbort.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/transaction/TestTransactionDSGWithLockWithAbort.java b/jena-arq/src/test/java/org/apache/jena/sparql/transaction/TestTransactionDSGWithLockWithAbort.java
deleted file mode 100644
index 9e0fbd6..0000000
--- a/jena-arq/src/test/java/org/apache/jena/sparql/transaction/TestTransactionDSGWithLockWithAbort.java
+++ /dev/null
@@ -1,38 +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.sparql.transaction;
-
-import org.apache.jena.query.Dataset ;
-import org.apache.jena.query.DatasetFactory ;
-import org.apache.jena.sparql.core.DatasetGraph ;
-import org.apache.jena.sparql.core.DatasetGraphFactory ;
-import org.apache.jena.sparql.core.DatasetGraphWithLock ;
-
-/** Version with abortImplemented == true */
-public class TestTransactionDSGWithLockWithAbort extends AbstractTestTransactionLifecycle
-{
- @Override
- protected Dataset create() {
- // The tests don't actually add/delete data.
- DatasetGraph dsg = DatasetGraphFactory.createTxnMem() ;
- DatasetGraphWithLock dsgl = new DatasetGraphWithLock(dsg, true) ;
- return DatasetFactory.wrap(dsgl) ;
- }
- }
-
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-arq/src/test/java/org/apache/jena/sparql/transaction/TestTransactionSupport.java
----------------------------------------------------------------------
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/transaction/TestTransactionSupport.java b/jena-arq/src/test/java/org/apache/jena/sparql/transaction/TestTransactionSupport.java
index 4eb1cac..46c955a 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/transaction/TestTransactionSupport.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/transaction/TestTransactionSupport.java
@@ -24,6 +24,7 @@ import java.util.List ;
import org.apache.jena.atlas.lib.Creator ;
import org.apache.jena.sparql.core.DatasetGraph ;
import org.apache.jena.sparql.core.DatasetGraphFactory ;
+import org.apache.jena.sparql.core.DatasetGraphZero;
import org.apache.jena.sparql.graph.GraphFactory ;
import org.junit.Assert ;
import org.junit.Test ;
@@ -50,7 +51,10 @@ public class TestTransactionSupport {
x.add(new Object[] {"createOneGraph" ,
(Creator<DatasetGraph>)()->
DatasetGraphFactory.createOneGraph(GraphFactory.createDefaultGraph()),
- true, false}) ;
+ true, true}) ;
+ x.add(new Object[] {"createZeroGraph" ,
+ (Creator<DatasetGraph>)()->new DatasetGraphZero(),
+ true, true}) ;
x.add(new Object[] {"create(Graph)",
(Creator<DatasetGraph>)()->
DatasetGraphFactory.create(GraphFactory.createDefaultGraph()),
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java
----------------------------------------------------------------------
diff --git a/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java b/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java
index 27db959..19b6ac0 100644
--- a/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java
+++ b/jena-base/src/main/java/org/apache/jena/atlas/lib/Lib.java
@@ -101,6 +101,17 @@ public class Lib
}
/**
+ * Read thread local, assuming that "null" means it does not exist for this thread.
+ * If null is read, the thread local is removed.
+ */
+ public static <X> X readThreadLocal(ThreadLocal<X> threadLocal) {
+ X x = threadLocal.get();
+ if ( x == null )
+ threadLocal.remove();
+ return x ;
+ }
+
+ /**
* @see CRC32
*/
public static long crc32(byte[] bytes)
http://git-wip-us.apache.org/repos/asf/jena/blob/edab900a/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/Transaction.java
----------------------------------------------------------------------
diff --git a/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/Transaction.java b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/Transaction.java
index d523e74..6bac45c 100644
--- a/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/Transaction.java
+++ b/jena-db/jena-dboe-transaction/src/main/java/org/apache/jena/dboe/transaction/txn/Transaction.java
@@ -181,10 +181,11 @@ public class Transaction implements TransactionInfo {
public void end() {
txnMgr.notifyEndStart(this) ;
if ( isWriteTxn() && getState() == ACTIVE ) {
- throw new TransactionException("Write transaction with no commit or abort") ;
//Log.warn(this, "Write transaction with no commit() or abort() before end()");
// Just the abort process.
- //abort$() ;
+ abort$() ;
+ endInternal() ;
+ throw new TransactionException("Write transaction with no commit() or abort() before end() - forced abort") ;
}
endInternal() ;
txnMgr.notifyEndFinish(this) ;