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 2012/08/18 12:39:27 UTC
svn commit: r1374552 - in /jena/trunk/jena-tdb: ./
src/main/java/com/hp/hpl/jena/tdb/ src/main/java/com/hp/hpl/jena/tdb/store/
src/main/java/com/hp/hpl/jena/tdb/sys/
src/main/java/com/hp/hpl/jena/tdb/transaction/
src/test/java/com/hp/hpl/jena/tdb/migra...
Author: andy
Date: Sat Aug 18 10:39:26 2012
New Revision: 1374552
URL: http://svn.apache.org/viewvc?rev=1374552&view=rev
Log:
+ Fix caching of last read trasnaction. JENA-299
+ Read txns do not now flush the delayed write queue immediately.
+ Add StoreConnection.flush()
forces a the delayed write queue to main database if no transactions active.
Modified:
jena/trunk/jena-tdb/ReleaseNotes.txt
jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/StoreConnection.java
jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/store/DatasetGraphTDB.java
jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/sys/TDBInternal.java
jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/sys/TDBMaker.java
jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/DatasetBuilderTxn.java
jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/DatasetGraphTransaction.java
jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/DatasetGraphTxn.java
jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/JournalControl.java
jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/Transaction.java
jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/TransactionManager.java
jena/trunk/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/migrate/AbstractTestTransaction.java
jena/trunk/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/transaction/AbstractTestTransSeq.java
Modified: jena/trunk/jena-tdb/ReleaseNotes.txt
URL: http://svn.apache.org/viewvc/jena/trunk/jena-tdb/ReleaseNotes.txt?rev=1374552&r1=1374551&r2=1374552&view=diff
==============================================================================
--- jena/trunk/jena-tdb/ReleaseNotes.txt (original)
+++ jena/trunk/jena-tdb/ReleaseNotes.txt Sat Aug 18 10:39:26 2012
@@ -1,9 +1,15 @@
ChangeLog for TDB
=================
+==== TDB 0.9.4
+
++ Cache read transaction datastructures and reuse view when possible.
++ Add StoreConnection flush() operation to push delayed writer-commits if possible.
++ JENA-290 - TDB txn creation touched stats unnecessarily, causing slow down.
+
==== TDB 0.9.3
-+ Batching of writer-commits to inprove write trasnaction performance.
++ Batching of writer-commits to improve write transaction performance.
==== TDB 0.9.2
Modified: jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/StoreConnection.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/StoreConnection.java?rev=1374552&r1=1374551&r2=1374552&view=diff
==============================================================================
--- jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/StoreConnection.java (original)
+++ jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/StoreConnection.java Sat Aug 18 10:39:26 2012
@@ -83,16 +83,6 @@ public class StoreConnection
return baseDSG.getLocation() ;
}
-// /**
-// * Return the associated transaction manager - do NOT use to manipulate
-// * transactions
-// */
-// public TransactionManager getTransMgr()
-// {
-// checkValid() ;
-// return transactionManager ;
-// }
-
/** Return a description of the transaction manager state */
public SysTxnState getTransMgrState()
{
@@ -114,16 +104,7 @@ public class StoreConnection
/**
- * Begin a transact// public static Graph _createGraph()
-// { return factory.createDatasetGraph().getDefaultGraph() ; }
-//
-// public static Graph _createGraph(Location loc)
-// {
-// // The code to choose the optimizer is in GraphTDBFactory.chooseOptimizer
-// return factory.createDatasetGraph(loc).getDefaultGraph() ;
-// }
-
-ion, giving it a label. Terminate a write transaction
+ * Begin a transaction, giving it a label. Terminate a write transaction
* with {@link Transaction#commit()} or {@link Transaction#abort()}.
* Terminate a write transaction with {@link Transaction#close()}.
*/
@@ -135,8 +116,10 @@ ion, giving it a label. Terminate a writ
}
/**
- * testing operation - do not use the base dataset without knowing how the
- * transaction system uses it
+ * Testing operation - do not use the base dataset without knowing how the
+ * transaction system uses it. The base dataset may not reflect the true state
+ * if pending commits are queued.
+ * @see #flush
*/
public DatasetGraphTDB getBaseDataset()
{
@@ -144,6 +127,27 @@ ion, giving it a label. Terminate a writ
return baseDSG ;
}
+ /** Flush the delayed write queue to th ebase storage.
+ * This can only be done if there are no active transactions.
+ * If there are active transactions, nothing is done but this is safe to call.
+ */
+ public void flush()
+ {
+ if ( ! haveUsedInTransaction() )
+ return ;
+ checkValid() ;
+ transactionManager.flush() ;
+ }
+
+ /** Indicate whether there are any active transactions.
+ * @see #getTransMgrState
+ */
+ public boolean activeTransactions()
+ {
+ checkValid() ;
+ return transactionManager.activeTransactions() ;
+ }
+
/** Flush the journal regardless - use with great case - do not use when transactions may be active. */
public void forceRecoverFromJournal()
{
Modified: jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/store/DatasetGraphTDB.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/store/DatasetGraphTDB.java?rev=1374552&r1=1374551&r2=1374552&view=diff
==============================================================================
--- jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/store/DatasetGraphTDB.java (original)
+++ jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/store/DatasetGraphTDB.java Sat Aug 18 10:39:26 2012
@@ -45,7 +45,7 @@ import com.hp.hpl.jena.tdb.transaction.D
import com.hp.hpl.jena.update.GraphStore ;
import com.hp.hpl.jena.update.UpdateRequest ;
-/** TDB Dataset - this is the class that creates a dataset over the storage via
+/** This is the class that creates a dataset over the storage via
* TripleTable, QuadTable and prefixes. These may be transactional.
*
* See also:
@@ -54,6 +54,7 @@ import com.hp.hpl.jena.update.UpdateRequ
* <li>{@link DatasetGraphTransaction} – class that provides the application with the right DatasetGraphTDB (base or transaction).</li>
* </ul>
*/
+final
public class DatasetGraphTDB extends DatasetGraphCaching
implements /*DatasetGraph,*/ Sync, Closeable, GraphStore, Session
{
Modified: jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/sys/TDBInternal.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/sys/TDBInternal.java?rev=1374552&r1=1374551&r2=1374552&view=diff
==============================================================================
--- jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/sys/TDBInternal.java (original)
+++ jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/sys/TDBInternal.java Sat Aug 18 10:39:26 2012
@@ -88,11 +88,15 @@ public class TDBInternal
/**
* Return the DatasetGraphTDB for a DatasetGraph, or null.
+ * May not be up-to-date.
*/
public static DatasetGraphTDB getDatasetGraphTDB(DatasetGraph dsg)
{
if ( dsg instanceof DatasetGraphTransaction )
- return ((DatasetGraphTransaction)dsg).getBaseDatasetGraph() ;
+ // Latest.
+ return ((DatasetGraphTransaction)dsg).getDatasetGraphToQuery() ;
+ // Core.
+ //.getBaseDatasetGraph() ;
if ( dsg instanceof DatasetGraphTDB )
return (DatasetGraphTDB)dsg ;
Modified: jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/sys/TDBMaker.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/sys/TDBMaker.java?rev=1374552&r1=1374551&r2=1374552&view=diff
==============================================================================
--- jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/sys/TDBMaker.java (original)
+++ jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/sys/TDBMaker.java Sat Aug 18 10:39:26 2012
@@ -105,7 +105,7 @@ public class TDBMaker
}
}
- /** The StoreConenction-cached base DatasetGraphTDB.*/
+ /** The StoreConnection-cached base DatasetGraphTDB.*/
private static class BuilderStoreConnectionBase implements DatasetGraphMakerTDB
{
@Override
Modified: jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/DatasetBuilderTxn.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/DatasetBuilderTxn.java?rev=1374552&r1=1374551&r2=1374552&view=diff
==============================================================================
--- jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/DatasetBuilderTxn.java (original)
+++ jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/DatasetBuilderTxn.java Sat Aug 18 10:39:26 2012
@@ -58,23 +58,23 @@ public class DatasetBuilderTxn
public DatasetBuilderTxn(TransactionManager txnMgr) { this.txnMgr = txnMgr ; }
- public DatasetGraphTDB build(Transaction transaction, ReadWrite mode, DatasetGraphTDB dsg)
+ public DatasetGraphTxn build(Transaction transaction, ReadWrite mode, DatasetGraphTDB dsg)
{
this.blockMgrs = dsg.getConfig().blockMgrs ;
this.nodeTables = dsg.getConfig().nodeTables ;
this.txn = transaction ;
this.dsg = dsg ;
- DatasetGraphTDB dsgTxn ;
+ DatasetGraphTDB dsgTDB ;
switch(mode)
{
- case READ : dsgTxn = buildReadonly() ; break ;
- case WRITE : dsgTxn = buildWritable() ; break ;
- default: dsgTxn = null ; // Silly Java.
+ case READ : dsgTDB = buildReadonly() ; break ;
+ case WRITE : dsgTDB = buildWritable() ; break ;
+ default: dsgTDB = null ; // Silly Java.
}
- dsgTxn = new DatasetGraphTxn(dsgTxn, txn) ;
+ DatasetGraphTxn dsgTxn = new DatasetGraphTxn(dsgTDB, txn) ;
// Copy context. Changes not propagated back to the base dataset.
dsgTxn.getContext().putAll(dsg.getContext()) ;
return dsgTxn ;
Modified: jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/DatasetGraphTransaction.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/DatasetGraphTransaction.java?rev=1374552&r1=1374551&r2=1374552&view=diff
==============================================================================
--- jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/DatasetGraphTransaction.java (original)
+++ jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/DatasetGraphTransaction.java Sat Aug 18 10:39:26 2012
@@ -41,7 +41,6 @@ public class DatasetGraphTransaction ext
// Two per-thread state variables:
// txn: ThreadLocalTxn -- the transactional , one time use dataset
// isInTransactionB: ThreadLocalBoolean -- flags true between begin and commit/abort, and end for read transactions.
-
static class ThreadLocalTxn extends ThreadLocal<DatasetGraphTxn>
{
@@ -97,7 +96,7 @@ public class DatasetGraphTransaction ext
DatasetGraphTxn dsgTxn = txn.get() ;
if ( dsgTxn == null )
throw new TDBTransactionException("In a transaction but no transactional DatasetGraph") ;
- return dsgTxn ;
+ return dsgTxn.getView() ;
}
if ( sConn.haveUsedInTransaction() )
Modified: jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/DatasetGraphTxn.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/DatasetGraphTxn.java?rev=1374552&r1=1374551&r2=1374552&view=diff
==============================================================================
--- jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/DatasetGraphTxn.java (original)
+++ jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/DatasetGraphTxn.java Sat Aug 18 10:39:26 2012
@@ -18,14 +18,15 @@
package com.hp.hpl.jena.tdb.transaction;
+import com.hp.hpl.jena.sparql.core.DatasetGraphWrapper ;
import com.hp.hpl.jena.tdb.store.DatasetGraphTDB ;
-/** A DatasetGraph that is a singe transaction.
+/** A DatasetGraph that is a single transaction.
* It does not support transactions, it is a transaction (single use).
*/
-public class DatasetGraphTxn extends DatasetGraphTDB
+public class DatasetGraphTxn extends DatasetGraphWrapper
{
- private final Transaction transaction ;
+ private Transaction transaction ;
public DatasetGraphTxn(DatasetGraphTDB dsg, Transaction txn)
{
@@ -35,6 +36,9 @@ public class DatasetGraphTxn extends Dat
public Transaction getTransaction() { return transaction ; }
+ /** Return the view (storage) for this transaction */
+ public DatasetGraphTDB getView() { return (DatasetGraphTDB)getWrapped() ; }
+
public void commit()
{
transaction.commit() ;
@@ -53,6 +57,7 @@ public class DatasetGraphTxn extends Dat
{
if ( transaction != null )
transaction.close() ;
+ transaction = null ;
}
}
Modified: jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/JournalControl.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/JournalControl.java?rev=1374552&r1=1374551&r2=1374552&view=diff
==============================================================================
--- jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/JournalControl.java (original)
+++ jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/JournalControl.java Sat Aug 18 10:39:26 2012
@@ -67,12 +67,6 @@ public class JournalControl
/** Recover a base storage DatasetGraph */
public static void recovery(DatasetGraphTDB dsg)
{
- if ( dsg instanceof DatasetGraphTxn )
- throw new TDBTransactionException("Recovery works on the base dataset, not a transactional one") ;
- // Later we may have ...
-// if ( dsg instanceof DatasetGraphTransaction )
-// throw new TDBTransactionException("Recovery works on the base dataset, not a transactional one") ;
-
if ( dsg.getLocation().isMem() )
return ;
@@ -114,9 +108,6 @@ public class JournalControl
*/
public static void recoverFromJournal(DatasetGraphTDB dsg, Journal jrnl )
{
- if ( dsg instanceof DatasetGraphTxn )
- throw new TDBTransactionException("Recovery works on the base dataset, not a transactional one") ;
-
if ( jrnl.isEmpty() )
return ;
Modified: jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/Transaction.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/Transaction.java?rev=1374552&r1=1374551&r2=1374552&view=diff
==============================================================================
--- jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/Transaction.java (original)
+++ jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/Transaction.java Sat Aug 18 10:39:26 2012
@@ -222,7 +222,12 @@ public class Transaction
public DatasetGraphTxn getActiveDataset() { return activedsg ; }
public void setActiveDataset(DatasetGraphTxn activedsg)
- { this.activedsg = activedsg ; }
+ {
+ this.activedsg = activedsg ;
+ if ( activedsg.getTransaction() != this )
+ Log.warn(this, "Active DSG does not point to this transaction; "+this) ;
+ }
+
public Journal getJournal() { return journal ; }
Modified: jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/TransactionManager.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/TransactionManager.java?rev=1374552&r1=1374551&r2=1374552&view=diff
==============================================================================
--- jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/TransactionManager.java (original)
+++ jena/trunk/jena-tdb/src/main/java/com/hp/hpl/jena/tdb/transaction/TransactionManager.java Sat Aug 18 10:39:26 2012
@@ -46,9 +46,6 @@ import com.hp.hpl.jena.tdb.sys.SystemTDB
public class TransactionManager
{
- // TODO Don't keep counters, keep lists.
- // TODO Useful logging.
-
private static boolean checking = true ;
private static Logger log = LoggerFactory.getLogger(TransactionManager.class) ;
@@ -90,16 +87,20 @@ public class TransactionManager
AtomicLong activeReaders = new AtomicLong(0) ;
AtomicLong activeWriters = new AtomicLong(0) ; // 0 or 1
+ public long getCountActiveReaders() { return activeReaders.get() ; }
+ public long getCountActiveWriters() { return activeWriters.get() ; }
+
// Misc stats
AtomicLong finishedReaders = new AtomicLong(0) ;
AtomicLong committedWriters = new AtomicLong(0) ;
AtomicLong abortedWriters = new AtomicLong(0) ;
- // This is the last read-transaction created
- // The read DatasetGraphTxn can be used by all the readers seeing the same view.
- // A write transaction clears this when it commits; future readers see the new state;
- // the first reader of a particular state creates teh view datasetgraph and sets the lastreader.
- private AtomicReference<DatasetGraphTxn> lastreader = new AtomicReference<DatasetGraphTxn>(null) ;
+ // This is the DatasetGraphTDB for the first read-transaction created for
+ // a particular view. The read DatasetGraphTDB can be used by all the readers
+ // seeing the same view.
+ // A write transaction clears this when it commits; the first reader of a
+ // particular state creates the view datasetgraph and sets the lastreader.
+ private AtomicReference<DatasetGraphTDB> currentReaderView = new AtomicReference<DatasetGraphTDB>(null) ;
// Ensure single writer.
private Semaphore writersWaiting = new Semaphore(1, true) ;
@@ -111,13 +112,6 @@ public class TransactionManager
private DatasetGraphTDB baseDataset ;
private Journal journal ;
- /* Various policies:
- * + MRSW : writer locks to write back; blocks until let trhough. Every reader takes an read lock.
- * + Writers write if free, else queue for a reader or writer to clearup.
- * + Async: there is a thread whose job it is to flush tot he base dataset (with an MRSW lock).
- */
-
- // Add queue unqueue?
/*
* The order of calls is:
* 1/ transactionStarts
@@ -129,7 +123,6 @@ public class TransactionManager
private interface TSM
{
- // Quert unqueue?
void transactionStarts(Transaction txn) ;
void transactionFinishes(Transaction txn) ;
void transactionCloses(Transaction txn) ;
@@ -154,6 +147,7 @@ public class TransactionManager
class TSM_Logger extends TSM_Base
{
+ TSM_Logger() {}
@Override public void readerStarts(Transaction txn) { log("start", txn) ; }
@Override public void readerFinishes(Transaction txn) { log("finish", txn) ; }
@Override public void writerStarts(Transaction txn) { log("begin", txn) ; }
@@ -164,6 +158,7 @@ public class TransactionManager
/** More detailed */
class TSM_LoggerDebug extends TSM_Base
{
+ TSM_LoggerDebug() {}
@Override public void readerStarts(Transaction txn) { logInternal("start", txn) ; }
@Override public void readerFinishes(Transaction txn) { logInternal("finish", txn) ; }
@Override public void writerStarts(Transaction txn) { logInternal("begin", txn) ; }
@@ -174,6 +169,7 @@ public class TransactionManager
class TSM_Counters implements TSM
{
+ TSM_Counters() {}
@Override public void transactionStarts(Transaction txn) { activeTransactions.add(txn) ; }
@Override public void transactionFinishes(Transaction txn) { activeTransactions.remove(txn) ; }
@Override public void transactionCloses(Transaction txn) { }
@@ -200,15 +196,17 @@ public class TransactionManager
// Safe mode.
// Take a READ lock over the base dataset.
// Write-back takes a WRITE lock.
- @Override public void readerStarts(Transaction txn) { txn.getBaseDataset().getLock().enterCriticalSection(Lock.READ) ; }
- @Override public void writerStarts(Transaction txn) { txn.getBaseDataset().getLock().enterCriticalSection(Lock.READ) ; }
+ @Override public void readerStarts(Transaction txn) { txn.getBaseDataset().getLock().enterCriticalSection(Lock.READ) ; }
+
+ @Override public void writerStarts(Transaction txn) { txn.getBaseDataset().getLock().enterCriticalSection(Lock.READ) ; }
// Currently, the writer semaphore is managed explicitly in the main code.
@Override public void readerFinishes(Transaction txn)
{
txn.getBaseDataset().getLock().leaveCriticalSection() ;
- processDelayedReplayQueue(txn) ;
+ if ( queue.size() >= QueueBatchSize )
+ processDelayedReplayQueue(txn) ;
}
@Override public void writerCommits(Transaction txn)
@@ -245,7 +243,8 @@ public class TransactionManager
@Override public void writerAborts(Transaction txn)
{
txn.getBaseDataset().getLock().leaveCriticalSection() ;
- processDelayedReplayQueue(txn) ;
+ if ( queue.size() >= QueueBatchSize )
+ processDelayedReplayQueue(txn) ;
}
}
@@ -299,7 +298,7 @@ public class TransactionManager
processDelayedReplayQueue(null) ;
journal.close() ;
}
-
+
public DatasetGraphTxn begin(ReadWrite mode)
{
return begin(mode, null) ;
@@ -307,6 +306,9 @@ public class TransactionManager
public /*for testing only*/ static final boolean DEBUG = false ;
+
+ /** Control logging - the logger must be set as well */
+ //public /*for testing only*/ static boolean LOG = false ;
public DatasetGraphTxn begin(ReadWrite mode, String label)
{
@@ -351,7 +353,7 @@ public class TransactionManager
if ( ! commitedAwaitingFlush.isEmpty() )
{
if ( DEBUG ) System.out.print(commitedAwaitingFlush.size()) ;
- dsg = commitedAwaitingFlush.get(commitedAwaitingFlush.size()-1).getActiveDataset() ;
+ dsg = commitedAwaitingFlush.get(commitedAwaitingFlush.size()-1).getActiveDataset().getView() ;
}
else
{
@@ -361,15 +363,16 @@ public class TransactionManager
log("begin$", txn) ;
- DatasetGraphTxn dsgTxn = createDSGTxn(dsg,txn, mode) ;
+ DatasetGraphTxn dsgTxn = createDSGTxn(dsg, txn, mode) ;
+
txn.setActiveDataset(dsgTxn) ;
// Empty for READ ; only WRITE transactions have components that need notifiying.
List<TransactionLifecycle> components = dsgTxn.getTransaction().lifecycleComponents() ;
-
+
if ( mode == ReadWrite.READ )
{
- // Consistency check.
+ // ---- Consistency check. View caching does not reset components.
if ( components.size() != 0 )
log.warn("read transaction, non-empty lifecycleComponents list") ;
}
@@ -387,28 +390,31 @@ public class TransactionManager
return txn ;
}
-
private DatasetGraphTxn createDSGTxn(DatasetGraphTDB dsg, Transaction txn, ReadWrite mode)
{
// A read transaction (if it has no lifecycle components) can be shared over all
// read transactions at the same commit level.
// lastreader
- DatasetGraphTxn dsgTxn ;
-
if ( mode == ReadWrite.READ )
{
// If a READ transaction, and a previously built one is cached, use it.
- dsgTxn = lastreader.get();
- if ( dsgTxn != null )
- return dsgTxn ;
+ DatasetGraphTDB dsgCached = currentReaderView.get();
+ if ( dsgCached != null )
+ {
+ // No components so we don't need to notify them.
+ // We can just reuse the storage dataset.
+ return new DatasetGraphTxn(dsgCached, txn) ;
+ }
}
- dsgTxn = (DatasetGraphTxn)new DatasetBuilderTxn(this).build(txn, mode, dsg) ;
+ DatasetGraphTxn dsgTxn = new DatasetBuilderTxn(this).build(txn, mode, dsg) ;
if ( mode == ReadWrite.READ )
- // If a READ transaction, cached it.
+ {
+ // If a READ transaction, cache the storage view.
// This is cleared when a WRITE commits
- lastreader.set(dsgTxn);
+ currentReaderView.set(dsgTxn.getView());
+ }
return dsgTxn ;
}
@@ -430,7 +436,7 @@ public class TransactionManager
{
case READ: break ;
case WRITE:
- lastreader.set(null) ; // Clear the READ transaction cache.
+ currentReaderView.set(null) ; // Clear the READ transaction cache.
writersWaiting.release() ; // Single writer: let another (waiting?) writer have a turn.
}
}
@@ -463,11 +469,15 @@ public class TransactionManager
transaction.signalEnacted() ;
}
+ /** Try to flush the delayed write queue - only happens if there are no active transactions */
+ public void flush()
+ {
+ processDelayedReplayQueue(null) ;
+ }
+
private void processDelayedReplayQueue(Transaction txn)
{
- // Sync'ed by notifyCommit.
- // If we knew which version of the DB each was looking at, we could reduce more often here.
- // [TxTDB:TODO]
+ // Can we do work?
if ( activeReaders.get() != 0 || activeWriters.get() != 0 )
{
if ( queue.size() > 0 && log() )
@@ -481,15 +491,15 @@ public class TransactionManager
System.out.print("!"+queue.size()+"!") ;
}
- if ( log() )
- log("Start flush delayed commits", txn) ;
-
if ( DEBUG ) checkNodesDatJrnl("1", txn) ;
if ( queue.size() == 0 && txn != null )
// Nothing to do - journal should be empty.
return ;
+ if ( log() )
+ log("Start flush delayed commits", txn) ;
+
while ( queue.size() > 0 )
{
// Currently, replay is replay everything
@@ -501,7 +511,7 @@ public class TransactionManager
if ( txn2.getMode() == ReadWrite.READ )
continue ;
if ( log() )
- log("Flush delayed commit of "+txn2.getLabel(), txn) ;
+ log(" Flush delayed commit of "+txn2.getLabel(), txn) ;
if ( DEBUG ) checkNodesDatJrnl("2", txn) ;
checkReplaySafe() ;
enactTransaction(txn2) ;
@@ -526,7 +536,7 @@ public class TransactionManager
}
- private static void checkNodesDatJrnl(String label, Transaction txn)
+ private void checkNodesDatJrnl(String label, Transaction txn)
{
if (txn != null)
{
@@ -559,7 +569,6 @@ public class TransactionManager
noteTxnClose(txn) ;
}
- // TODO Collapse these.
private void noteStartTxn(Transaction transaction)
{
switch (transaction.getMode())
@@ -624,12 +633,17 @@ public class TransactionManager
return journal ;
}
- private static boolean log()
+ // ---- Logging
+ // Choose log output once when this object is created.
+
+ private final boolean logstate = (syslog.isDebugEnabled() || log.isDebugEnabled()) ;
+
+ private boolean log()
{
- return syslog.isDebugEnabled() || log.isDebugEnabled() ;
+ return logstate ;
}
- private static void log(String msg, Transaction txn)
+ private void log(String msg, Transaction txn)
{
if ( ! log() )
return ;
@@ -644,7 +658,8 @@ public class TransactionManager
if ( ! log() )
return ;
String txnStr = ( txn == null ) ? "<null>" : txn.getLabel() ;
- System.err.printf(format("%6s %s -- %s", action, txnStr, state())) ;
+ //System.err.printf(format("%6s %s -- %s", action, txnStr, state())) ;
+ logger().debug(format("%6s %s -- %s", action, txnStr, state())) ;
}
private static Logger logger()
Modified: jena/trunk/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/migrate/AbstractTestTransaction.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/migrate/AbstractTestTransaction.java?rev=1374552&r1=1374551&r2=1374552&view=diff
==============================================================================
--- jena/trunk/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/migrate/AbstractTestTransaction.java (original)
+++ jena/trunk/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/migrate/AbstractTestTransaction.java Sat Aug 18 10:39:26 2012
@@ -101,7 +101,20 @@ public abstract class AbstractTestTransa
@Test public void transaction_7()
{
- // .end is not necessary
+ Dataset ds = create() ;
+ ds.begin(ReadWrite.READ) ;
+ assertTrue(ds.isInTransaction()) ;
+ ds.commit() ;
+ assertFalse(ds.isInTransaction()) ;
+
+ ds.begin(ReadWrite.READ) ;
+ assertTrue(ds.isInTransaction()) ;
+ ds.commit() ;
+ assertFalse(ds.isInTransaction()) ;
+ }
+
+ @Test public void transaction_8()
+ {
Dataset ds = create() ;
ds.begin(ReadWrite.WRITE) ;
assertTrue(ds.isInTransaction()) ;
@@ -113,6 +126,32 @@ public abstract class AbstractTestTransa
ds.commit() ;
assertFalse(ds.isInTransaction()) ;
}
+
+ @Test public void transaction_9()
+ {
+ Dataset ds = create() ;
+ ds.begin(ReadWrite.WRITE) ;
+ assertTrue(ds.isInTransaction()) ;
+ ds.commit() ;
+ assertFalse(ds.isInTransaction()) ;
+ ds.end() ;
+ assertFalse(ds.isInTransaction()) ;
+
+ ds.begin(ReadWrite.READ) ;
+ assertTrue(ds.isInTransaction()) ;
+ ds.commit() ;
+ assertFalse(ds.isInTransaction()) ;
+ ds.end() ;
+ assertFalse(ds.isInTransaction()) ;
+
+ ds.begin(ReadWrite.READ) ;
+ assertTrue(ds.isInTransaction()) ;
+ ds.commit() ;
+ assertFalse(ds.isInTransaction()) ;
+ ds.end() ;
+ assertFalse(ds.isInTransaction()) ;
+ }
+
}
Modified: jena/trunk/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/transaction/AbstractTestTransSeq.java
URL: http://svn.apache.org/viewvc/jena/trunk/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/transaction/AbstractTestTransSeq.java?rev=1374552&r1=1374551&r2=1374552&view=diff
==============================================================================
--- jena/trunk/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/transaction/AbstractTestTransSeq.java (original)
+++ jena/trunk/jena-tdb/src/test/java/com/hp/hpl/jena/tdb/transaction/AbstractTestTransSeq.java Sat Aug 18 10:39:26 2012
@@ -89,6 +89,7 @@ public abstract class AbstractTestTransS
assertTrue(dsg2.contains(q)) ;
dsg2.end() ;
+ sConn.flush() ;
DatasetGraph dsg = sConn.getBaseDataset() ;
assertTrue(dsg.contains(q)) ;
@@ -109,6 +110,7 @@ public abstract class AbstractTestTransS
assertFalse(dsg2.contains(q)) ;
dsg2.end() ;
+ sConn.flush() ;
DatasetGraph dsg = sConn.getBaseDataset() ;
assertFalse(dsg.contains(q)) ;
}
@@ -132,6 +134,7 @@ public abstract class AbstractTestTransS
assertTrue(dsgR2.contains(q2)) ;
dsgR2.end() ;
+ sConn.flush() ;
DatasetGraph dsg = sConn.getBaseDataset() ;
assertTrue(dsg.contains(q1)) ;
assertTrue(dsg.contains(q2)) ;
@@ -184,6 +187,7 @@ public abstract class AbstractTestTransS
assertTrue(dsgR2.contains(q)) ;
dsgR2.end() ;
+ sConn.flush() ;
DatasetGraph dsg = sConn.getBaseDataset() ;
assertTrue(dsg.contains(q)) ;
}
@@ -240,6 +244,7 @@ public abstract class AbstractTestTransS
assertTrue(dsgR2.contains(q2)) ;
dsgR2.end() ;
+ sConn.flush() ;
DatasetGraph dsg = sConn.getBaseDataset() ;
assertTrue(dsg.contains(q1)) ;
assertTrue(dsg.contains(q2)) ;
@@ -268,6 +273,7 @@ public abstract class AbstractTestTransS
dsgR1.end() ;
+ sConn.flush() ;
DatasetGraph dsg = sConn.getBaseDataset() ;
assertFalse(dsg.contains(q2)) ;
assertTrue(dsg.contains(q3)) ;
@@ -304,6 +310,7 @@ public abstract class AbstractTestTransS
dsgR1.end() ;
+ sConn.flush() ;
DatasetGraph dsg = sConn.getBaseDataset() ;
assertTrue(dsg.contains(q1)) ;
assertFalse(dsg.contains(q2)) ;
@@ -328,7 +335,9 @@ public abstract class AbstractTestTransS
DatasetGraphTxn dsgR2 = sConn.begin(ReadWrite.READ) ;
assertTrue(dsgR2.contains(q)) ;
+ dsgR2.end() ;
+ sConn.flush() ;
DatasetGraph dsg = sConn.getBaseDataset() ;
assertTrue(dsg.contains(q)) ;
}
@@ -353,6 +362,7 @@ public abstract class AbstractTestTransS
assertTrue(dsgR2.contains(q)) ;
dsgR2.end() ;
+ sConn.flush() ;
DatasetGraph dsg = sConn.getBaseDataset() ;
assertTrue(dsg.contains(q)) ;
}
@@ -377,6 +387,7 @@ public abstract class AbstractTestTransS
dsgR1.end() ;
dsgR2.end() ;
+ sConn.flush() ;
DatasetGraph dsg = sConn.getBaseDataset() ;
assertTrue(dsg.contains(q)) ;
}
@@ -406,6 +417,7 @@ public abstract class AbstractTestTransS
dsgR1.end() ;
dsgR2.end() ;
+ sConn.flush() ;
DatasetGraph dsg = sConn.getBaseDataset() ;
assertTrue(dsg.contains(q1)) ;
assertTrue(dsg.contains(q2)) ;
@@ -459,6 +471,7 @@ public abstract class AbstractTestTransS
dsgR1.end() ;
+ sConn.flush() ;
DatasetGraphTDB dsg = sConn.getBaseDataset() ;
assertTrue(dsg.contains(q1)) ;
assertTrue(dsg.contains(q2)) ;