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/30 11:18:41 UTC
[3/5] jena git commit: JENA-1469: Adjust internal tracking state
across promotion
JENA-1469: Adjust internal tracking state across promotion
Project: http://git-wip-us.apache.org/repos/asf/jena/repo
Commit: http://git-wip-us.apache.org/repos/asf/jena/commit/fb172399
Tree: http://git-wip-us.apache.org/repos/asf/jena/tree/fb172399
Diff: http://git-wip-us.apache.org/repos/asf/jena/diff/fb172399
Branch: refs/heads/master
Commit: fb172399ff2181a8f5f82e5988424defdf38da67
Parents: 3ac175b
Author: Andy Seaborne <an...@apache.org>
Authored: Sat Jan 27 17:11:22 2018 +0000
Committer: Andy Seaborne <an...@apache.org>
Committed: Sat Jan 27 17:11:22 2018 +0000
----------------------------------------------------------------------
.../transaction/AbstractTestTransPromote.java | 26 ++++-----
.../AbstractTestTransactionLifecycle.java | 24 +++++++-
.../tdb/transaction/TransactionManager.java | 59 ++++++++++++--------
3 files changed, 72 insertions(+), 37 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jena/blob/fb172399/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 9134668..1ca1379 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
@@ -244,18 +244,6 @@ public abstract class AbstractTestTransPromote {
}) ;
}
- @Test
- public void promote_10() { promote_readCommit_txnCommit(TxnType.READ_COMMITTED_PROMOTE, true) ; }
-
- @Test
- public void promote_11() { promote_readCommit_txnCommit(TxnType.READ_COMMITTED_PROMOTE, false) ; }
-
- @Test
- public void promote_12() {
- expect(()->promote_readCommit_txnCommit(TxnType.READ_PROMOTE, true) ,
- getTransactionExceptionClass()) ;
- }
-
@SafeVarargs
private final void expect(Runnable runnable, Class<? extends Exception>...classes) {
try {
@@ -271,6 +259,18 @@ public abstract class AbstractTestTransPromote {
}
@Test
+ public void promote_10() { promote_readCommit_txnCommit(TxnType.READ_COMMITTED_PROMOTE, true) ; }
+
+ @Test
+ public void promote_11() { promote_readCommit_txnCommit(TxnType.READ_COMMITTED_PROMOTE, false) ; }
+
+ @Test
+ public void promote_12() {
+ expect(()->promote_readCommit_txnCommit(TxnType.READ_PROMOTE, true) ,
+ getTransactionExceptionClass()) ;
+ }
+
+ @Test
public void promote_13() { promote_readCommit_txnCommit(TxnType.READ_PROMOTE, false) ; }
private void promote_readCommit_txnCommit(TxnType txnType, boolean asyncCommit) {
@@ -388,7 +388,7 @@ public abstract class AbstractTestTransPromote {
} catch (InterruptedException | ExecutionException e1) { throw new RuntimeException(e1) ; }
}
- // This would locks up because of a WRITE-WRITE deadly embrace.
+ // This would lock up because of a WRITE-WRITE deadly embrace.
// @Test(expected=JenaTransactionException.class)
// public void promote11() { test2(TxnMode.WRITE); }
http://git-wip-us.apache.org/repos/asf/jena/blob/fb172399/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 c1043b8..ec80425 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
@@ -235,6 +235,17 @@ public abstract class AbstractTestTransactionLifecycle extends BaseTest
ds.end();
}
+ // JENA-1469
+ @Test
+ public void transaction_p06() {
+ transaction_promote_write(TxnType.READ_COMMITTED_PROMOTE);
+ }
+
+ @Test
+ public void transaction_p07() {
+ transaction_promote_write(TxnType.READ_PROMOTE);
+ }
+
@Test(expected=JenaException.class)
public void transaction_err_read_promote() {
assumeTrue(supportsPromote()) ;
@@ -245,9 +256,18 @@ public abstract class AbstractTestTransactionLifecycle extends BaseTest
ds.commit();
ds.end();
}
-
- // XXX READ_PROMOTE -> update -> fail promote/boolean.
+ private void transaction_promote_write(TxnType txnType) {
+ Dataset ds = create() ;
+ ds.begin(txnType);
+ ds.promote();
+ ds.commit();
+ ds.end();
+ ds.begin(TxnType.WRITE);
+ ds.commit();
+ ds.end();
+ }
+
// Patterns.
@Test
public void transaction_pattern_01() {
http://git-wip-us.apache.org/repos/asf/jena/blob/fb172399/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 10e8b44..e9c4797 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
@@ -163,7 +163,7 @@ public class TransactionManager
void transactionCloses(Transaction txn) ;
void readerStarts(Transaction txn) ;
void readerFinishes(Transaction txn) ;
- void transactionPromotes(Transaction txn) ;
+ void transactionPromotes(Transaction txnOld, Transaction txnNew) ;
void writerStarts(Transaction txn) ;
void writerCommits(Transaction txn) ;
void writerAborts(Transaction txn) ;
@@ -175,7 +175,7 @@ public class TransactionManager
@Override public void transactionCloses(Transaction txn) {}
@Override public void readerStarts(Transaction txn) {}
@Override public void readerFinishes(Transaction txn) {}
- @Override public void transactionPromotes(Transaction txn) {}
+ @Override public void transactionPromotes(Transaction txnOld, Transaction txnNew) {}
@Override public void writerStarts(Transaction txn) {}
@Override public void writerCommits(Transaction txn) {}
@Override public void writerAborts(Transaction txn) {}
@@ -185,7 +185,8 @@ public class TransactionManager
TSM_Logger() {}
@Override public void readerStarts(Transaction txn) { log("start", txn) ; }
@Override public void readerFinishes(Transaction txn) { log("finish", txn) ; }
- @Override public void transactionPromotes(Transaction txn) { log("promote", txn) ; }
+ @Override public void transactionPromotes(Transaction txnOld, Transaction txnNew)
+ { log("promote(old)", txnOld) ; log("promote(new)", txnNew) ; }
@Override public void writerStarts(Transaction txn) { log("begin", txn) ; }
@Override public void writerCommits(Transaction txn) { log("commit", txn) ; }
@Override public void writerAborts(Transaction txn) { log("abort", txn) ; }
@@ -196,7 +197,8 @@ public class TransactionManager
TSM_LoggerDebug() {}
@Override public void readerStarts(Transaction txn) { logInternal("start", txn) ; }
@Override public void readerFinishes(Transaction txn) { logInternal("finish", txn) ; }
- @Override public void transactionPromotes(Transaction txn) { logInternal("promote", txn) ; }
+ @Override public void transactionPromotes(Transaction txnOld, Transaction txnNew)
+ { logInternal("promote(old)", txnOld) ; logInternal("promote(new)", txnNew) ; }
@Override public void writerStarts(Transaction txn) { logInternal("begin", txn) ; }
@Override public void writerCommits(Transaction txn) { logInternal("commit", txn) ; }
@Override public void writerAborts(Transaction txn) { logInternal("abort", txn) ; }
@@ -209,7 +211,10 @@ public class TransactionManager
@Override public void transactionCloses(Transaction txn) { }
@Override public void readerStarts(Transaction txn) { inc(activeReaders) ; }
@Override public void readerFinishes(Transaction txn) { dec(activeReaders) ; inc(finishedReaders); }
- @Override public void transactionPromotes(Transaction txn) { dec(activeReaders) ; inc(finishedReaders); inc(activeWriters); }
+
+ @Override public void transactionPromotes(Transaction txnOld, Transaction txnNew)
+ { dec(activeReaders) ; inc(finishedReaders); inc(activeWriters); }
+
@Override public void writerStarts(Transaction txn) { inc(activeWriters) ; }
@Override public void writerCommits(Transaction txn) { dec(activeWriters) ; inc(committedWriters) ; }
@Override public void writerAborts(Transaction txn) { dec(activeWriters) ; inc(abortedWriters) ; }
@@ -236,6 +241,12 @@ public class TransactionManager
// Currently, the writer semaphore is managed explicitly in the main code.
+ @Override public void transactionPromotes(Transaction txnOld, Transaction txnNew) {
+ // Switch locks.
+ txnOld.getBaseDataset().getLock().leaveCriticalSection() ;
+ txnNew.getBaseDataset().getLock().enterCriticalSection(Lock.READ) ;
+ }
+
@Override
public void readerFinishes(Transaction txn) {
txn.getBaseDataset().getLock().leaveCriticalSection() ;
@@ -342,7 +353,9 @@ public class TransactionManager
acquireWriterLock(true) ;
}
// entry synchronized part
- return begin$(txnType, originalTxnType, label) ;
+ DatasetGraphTxn dsgtxn = begin$(txnType, originalTxnType, label) ;
+ noteTxnStart(dsgtxn.getTransaction()) ;
+ return dsgtxn;
}
/** Ensure a DatasetGraphTxn is for a write transaction.
@@ -377,11 +390,9 @@ public class TransactionManager
// Can also promote - may need to wait for active writers.
// Go through begin for the writers lock.
if ( txnType == TxnType.READ_COMMITTED_PROMOTE ) {
- // Full begin cycle.
- DatasetGraphTxn dsgtxn2 = beginInternal(TxnType.WRITE, txnType, txn.getLabel()) ;
- // Junk the old one.
- noteTxnPromote(txn, dsgtxn2.getTransaction());
- return dsgtxn2 ;
+ acquireWriterLock(true);
+ // No need to sync - we just queue as a writer.
+ return promoteExec$(dsgtxn, txnType);
}
// First check, without the writer lock. Fast fail.
@@ -402,25 +413,31 @@ public class TransactionManager
// Potentially blocking - must be outside 'synchronized' so that any active writer
// can commit/abort. Otherwise, we have deadlock.
acquireWriterLock(true) ;
-
// Do the synchronized stuff.
- return promote2$(dsgtxn, txnType) ;
+ return promoteSync$(dsgtxn, txnType) ;
}
synchronized
- private DatasetGraphTxn promote2$(DatasetGraphTxn dsgtxn, TxnType originalTxnType) {
+ private DatasetGraphTxn promoteSync$(DatasetGraphTxn dsgtxn, TxnType originalTxnType) {
Transaction txn = dsgtxn.getTransaction() ;
// Writers may have happened between the first check of the active writers may have committed.
if ( txn.getVersion() != version.get() ) {
releaseWriterLock();
return null;
}
- // Use begin$ (not beginInternal) - we have the writers lock.
+ return promoteExec$(dsgtxn, originalTxnType);
+ }
+
+ private DatasetGraphTxn promoteExec$(DatasetGraphTxn dsgtxn, TxnType originalTxnType) {
+ // Use begin$ (not beginInternal)
+ // We have the writers lock.
+ // We keep the exclusivity lock.
+ Transaction txn = dsgtxn.getTransaction() ;
DatasetGraphTxn dsgtxn2 = begin$(TxnType.WRITE, originalTxnType, txn.getLabel()) ;
noteTxnPromote(txn, dsgtxn2.getTransaction());
return dsgtxn2 ;
}
-
+
// If DatasetGraphTransaction has a sync lock on sConn, this
// does not need to be sync'ed. But it's possible to use some
// of the low level objects directly so we'll play safe.
@@ -450,6 +467,7 @@ public class TransactionManager
txn.setActiveDataset(dsgTxn) ;
// Empty for READ ; only WRITE transactions have components that need notifying.
+ // Promote is a WRITE transaction starting.
List<TransactionLifecycle> components = dsgTxn.getTransaction().lifecycleComponents() ;
if ( mode == ReadWrite.READ ) {
@@ -460,8 +478,6 @@ public class TransactionManager
for ( TransactionLifecycle component : components )
component.begin(dsgTxn.getTransaction()) ;
-
- noteTxnStart(txn) ;
return dsgTxn ;
}
@@ -870,10 +886,9 @@ public class TransactionManager
private void noteTxnPromote(Transaction transaction, Transaction transaction2) {
activeTransactions.remove(transaction);
activeTransactions.add(transaction2);
- transactionPromotes(transaction) ;
+ transactionPromotes(transaction, transaction2) ;
}
-
private void noteTxnCommit(Transaction transaction) {
switch (transaction.getTxnMode())
{
@@ -1011,10 +1026,10 @@ public class TransactionManager
tsm.readerFinishes(txn) ;
}
- private void transactionPromotes(Transaction txn) {
+ private void transactionPromotes(Transaction txnOld, Transaction txnNew) {
for ( TSM tsm : actions )
if ( tsm != null )
- tsm.transactionPromotes(txn);
+ tsm.transactionPromotes(txnOld, txnNew);
}
private void writerStarts(Transaction txn) {