/** Force flushing the queue by entering exclusive mode.*/ private void exclusiveFlushQueue() { startExclusiveMode(true) ; finishExclusiveMode(); }
private StoreConnection(DatasetGraphTDB dsg) { baseDSG = dsg; transactionManager = new TransactionManager(baseDSG); }
private DatasetGraphTxn beginInternal(TxnType txnType, TxnType originalTxnType, String label) { // The exclusivitylock surrounds the entire transaction cycle. // Paired with notifyCommit, notifyAbort. startNonExclusive(); // Not synchronized (else blocking on semaphore will never wake up // because Semaphore.release is inside synchronized). // Allow only one active writer. 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. acquireWriterLock(true) ; } // entry synchronized part DatasetGraphTxn dsgtxn = begin$(txnType, originalTxnType, label) ; noteTxnStart(dsgtxn.getTransaction()) ; return dsgtxn; }
private void readerFinishesWorker(Transaction txn) { if ( checkForJournalFlush() ) processDelayedReplayQueue(txn) ; }
@Test public void exclusive_3() { DatasetGraph dsg = TDBFactory.createDatasetGraph() ; TransactionManager txnmgr = TDBInternal.getTransactionManager(dsg) ; ReentrantReadWriteLock rwx = (ReentrantReadWriteLock)txnmgr.getExclusivityLock$() ; checkLock(rwx, 0, 0) ; txnmgr.startExclusiveMode(); checkLock(rwx, 0, 1) ; txnmgr.finishExclusiveMode(); checkLock(rwx, 0, 0) ; }
@Test public void exclusive_4() { DatasetGraph dsg = TDBFactory.createDatasetGraph() ; TransactionManager txnmgr = TDBInternal.getTransactionManager(dsg) ; ReentrantReadWriteLock rwx = (ReentrantReadWriteLock)txnmgr.getExclusivityLock$() ; checkLock(rwx, 0, 0) ; boolean b = txnmgr.tryExclusiveMode(); Assert.assertTrue("Exclusive 1", b); checkLock(rwx, 0, 1) ; txnmgr.finishExclusiveMode(); checkLock(rwx, 0, 0) ; b = txnmgr.tryExclusiveMode(); Assert.assertTrue("Exclusive 2", b); }
private void writerCommitsWorker(Transaction txn) { if ( activeReaders.get() == 0 && checkForJournalFlush() ) { // Can commit immediately. // Ensure the queue is empty though. // Could simply add txn to the commit queue and do it that way. if ( log() ) log("Commit immediately", txn) ; // Currently, all we need is // JournalControl.replay(txn) ; // because that plays queued transactions. // But for long term generallity, at the cost of one check of the journal size // we do this sequence. processDelayedReplayQueue(txn) ; enactTransaction(txn) ; JournalControl.replay(txn) ; } else { // Can't write back to the base database at the moment. commitedAwaitingFlush.add(txn) ; maxQueue = Math.max(commitedAwaitingFlush.size(), maxQueue) ; if ( log() ) log("Add to pending queue", txn) ; queue.add(txn) ; } }
acquireWriterLock(true); return promoteExec$(dsgtxn, originalTxnType); acquireWriterLock(true) ; return promoteSync$(dsgtxn, originalTxnType) ;
/** Stop managing a location. Use with great care (testing only). */ public static synchronized void expel(Location location, boolean force) { StoreConnection sConn = cache.get(location) ; if (sConn == null) return ; if (!force && sConn.transactionManager.activeTransactions()) throw new TDBTransactionException("Can't expel: Active transactions for location: " + location) ; // No transactions at this point (or we don't care and are clearing up forcefully.) sConn.transactionManager.closedown() ; sConn.baseDSG.close() ; sConn.isValid = false ; cache.remove(location) ; ChannelManager.release(sConn.transactionManager.getJournal().getFilename()) ; // Release the lock if (SystemTDB.DiskLocationMultiJvmUsagePrevention) { if (location.getLock().isOwned()) { location.getLock().release(); } else if (location.getLock().canLock()) { SystemTDB.errlog.warn("Location " + location.getDirectoryPath() + " was not locked, if another JVM accessed this location simultaneously data corruption may have occurred"); } } }
/** Try to enter exclusive mode. * If return is true, then are no active transactions on return and new transactions will be held up in 'begin'. * If false, there is an in-progress transactions. * Return to normal (release waiting transactions, allow new transactions) * with {@link #finishExclusiveMode}. * <p> * The call must not itself be in a transaction (this call will return false). */ public boolean tryExclusiveMode() { return startExclusiveMode(false); }
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 ; }
/** Block until no writers are active or, optionally, return if can't at the moment. * Return 'true' if the operation succeeded. * <p> * If it returns true, the application must call {@link #enableWriters} later. * * @see #blockWriters() * @see #enableWriters() */ public boolean tryBlockWriters() { return acquireWriterLock(false) ; }
/** * 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()}. */ public DatasetGraphTxn begin(TxnType mode, String label) { checkValid(); checkTransactional(); return transactionManager.begin(mode, label); }
public DatasetGraphText(DatasetGraph dsg, TextIndex index, TextDocProducer producer, boolean closeIndexOnClose) { super(dsg, producer) ; this.textIndex = index ; dftGraph = GraphView.createDefaultGraph(this) ; this.closeIndexOnClose = closeIndexOnClose; if ( org.apache.jena.tdb.sys.TDBInternal.isTDB1(dsg) ) { TransactionManager txnMgr = org.apache.jena.tdb.sys.TDBInternal.getTransactionManager(dsg); txnMgr.addAdditionComponent(new TextIndexTDB1(textIndex)); commitAction = delegateCommit; abortAction = delegateAbort; } else if ( org.apache.jena.tdb2.sys.TDBInternal.isTDB2(dsg) ) { TransactionCoordinator coord = org.apache.jena.tdb2.sys.TDBInternal.getTransactionCoordinator(dsg); // Does not overlap with the ids used by TDB2. byte[] componentID = { 2,4,6,10 } ; TransactionalComponent tc = new TextIndexDB(ComponentId.create(null, componentID), textIndex); coord.modify(()->coord.add(tc)); commitAction = delegateCommit; abortAction = delegateAbort; } else { commitAction = nonDelegatedCommit; abortAction = nonDelegatedAbort; } }
public DatasetGraphTxn begin(TxnType txnType, String label) { return beginInternal(txnType, txnType, label); }
/** Indicate whether there are any active transactions. * @see #getTransMgrState */ public boolean activeTransactions() { checkValid(); return transactionManager.activeTransactions(); }
@Test public void exclusive_3() { DatasetGraph dsg = TDBFactory.createDatasetGraph() ; TransactionManager txnmgr = TDBInternal.getTransactionManager(dsg) ; ReentrantReadWriteLock rwx = (ReentrantReadWriteLock)txnmgr.getExclusivityLock$() ; checkLock(rwx, 0, 0) ; txnmgr.startExclusiveMode(); checkLock(rwx, 0, 1) ; txnmgr.finishExclusiveMode(); checkLock(rwx, 0, 0) ; }
@Test public void exclusive_4() { DatasetGraph dsg = TDBFactory.createDatasetGraph() ; TransactionManager txnmgr = TDBInternal.getTransactionManager(dsg) ; ReentrantReadWriteLock rwx = (ReentrantReadWriteLock)txnmgr.getExclusivityLock$() ; checkLock(rwx, 0, 0) ; boolean b = txnmgr.tryExclusiveMode(); Assert.assertTrue("Exclusive 1", b); checkLock(rwx, 0, 1) ; txnmgr.finishExclusiveMode(); checkLock(rwx, 0, 0) ; b = txnmgr.tryExclusiveMode(); Assert.assertTrue("Exclusive 2", b); }
/** Enter exclusive mode. * <p> * There are no active transactions on return; new transactions will be held up in 'begin'. * Return to normal (release waiting transactions, allow new transactions) * with {@link #finishExclusiveMode}. * <p> * The caller must not be inside a transaction associated with this TransactionManager. * (The call will block waiting for that transaction to finish.) */ public void startExclusiveMode() { startExclusiveMode(true); }
private void writerAbortsWorker(Transaction txn) { if ( checkForJournalFlush() ) processDelayedReplayQueue(txn) ; }