private Transaction createTransaction(DatasetGraphTDB dsg, TxnType txnType, TxnType originalTxnType, String label) { if ( originalTxnType == null ) originalTxnType = txnType; Transaction txn = new Transaction(dsg, version.get(), txnType, initialMode(txnType), transactionId.getAndIncrement(), originalTxnType, label, this) ; // Add the extras. additionalComponents.forEach(txn::addAdditionaComponent); return txn ; }
synchronized /*package*/ void notifyClose(Transaction txn) { // Caution - not called if "Transactional.end() is not called." if ( txn.getState() == TxnState.ACTIVE ) { // The application error case for begin(WRITE)...end() is handled in Trasnaction.close(). // This is internal checking. String x = txn.getBaseDataset().getLocation().getDirectoryPath() ; syslog.warn("close: Transaction not commited or aborted: Transaction: "+txn.getTxnId()+" @ "+x) ; // Force abort then close txn.abort() ; txn.close() ; return ; } noteTxnClose(txn) ; }
@Override public void beginIterator(Iterator<?> iterator) { checkIfClosed() ; transaction.addIterator(iterator) ; // Don't pass down the beginIterator call - we track and manage here, not lower down. //blockMgr.beginIterator(iterator) ; }
/** The stage in a commit after committing - make the changes permanent in the base data */ private void enactTransaction(Transaction transaction) { transaction.forAllComponents(x->x.enactCommitted(transaction)); transaction.forAllComponents(x->x.clearupCommitted(transaction)); transaction.signalEnacted() ; }
public static void replay(Transaction transaction) { if ( syslog.isDebugEnabled()) syslog.debug("Replay "+transaction.getLabel()) ; Journal journal = transaction.getJournal() ; DatasetGraphTDB dsg = transaction.getBaseDataset() ; // Currently, we (crudely) replay the whole journal. replay(journal, dsg.getConfig()) ; }
prepare() ; } catch (RuntimeException ex) if ( isIOException(ex) ) SystemTDB.errlog.warn("IOException during 'prepare' : attempting transaction abort: "+ex.getMessage()) ; else state = TxnState.ACTIVE ; try { abort() ; } catch (RuntimeException ex2) if ( isIOException(ex) ) SystemTDB.errlog.warn("IOException during 'commit' : transaction status not known (but not a partial commit): "+ex.getMessage()) ; else committed() ; } catch (RuntimeException ex) { if ( isIOException(ex) ) SystemTDB.errlog.warn("IOException during 'committed'"+ex.getMessage()) ; else if ( isIOException(ex) ) SystemTDB.errlog.warn("IOException after commit point : transaction commited but internal status not recorded properly : "+ex.getMessage()) ; else
@Override public void readerFinishes(Transaction txn) { txn.getBaseDataset().getLock().leaveCriticalSection() ; readerFinishesWorker(txn) ; }
public BlockMgrJournal(Transaction txn, FileRef fileRef, BlockMgr underlyingBlockMgr) { Context context = txn.getBaseDataset().getContext() ; String mode = (null != context) ? (String) context.get(TDB.transactionJournalWriteBlockMode, "") : "" ; if ("direct".equalsIgnoreCase(mode)) writeBlockBufferAllocator = new BufferAllocatorDirect() ; else if ("mapped".equalsIgnoreCase(mode)) writeBlockBufferAllocator = new BufferAllocatorMapped(SystemTDB.BlockSize) ; else writeBlockBufferAllocator = new BufferAllocatorMem() ; reset(txn, fileRef, underlyingBlockMgr) ; if ( txn.getTxnMode() == ReadWrite.READ && underlyingBlockMgr instanceof BlockMgrJournal ) System.err.println("Two level BlockMgrJournal") ; }
throw new TDBTransactionException("Transaction has already committed or aborted") ; try { forAllComponents(x->x.abort(this)) ; if ( isIOException(ex) ) SystemTDB.errlog.warn("IOException during 'abort' : " + ex.getMessage()) ; else if ( isIOException(ex) ) SystemTDB.errlog.warn("IOException during post-abort (transaction did abort): "+ex.getMessage()) ; else
synchronized private DatasetGraphTxn begin$(TxnType txnType, TxnType originalTxnType, String label) { Objects.requireNonNull(txnType); if ( txnType == TxnType.WRITE && activeWriters.get() > 0 ) // Guard throw new TDBTransactionException("Existing active write transaction") ; if ( DEBUG ) switch ( txnType ) { case READ : System.out.print("r") ; break ; case WRITE : System.out.print("w") ; break ; case READ_COMMITTED_PROMOTE : System.out.print("r(cp)") ; break ; case READ_PROMOTE : System.out.print("rp") ; break ; } DatasetGraphTDB dsg = determineBaseDataset() ; Transaction txn = createTransaction(dsg, txnType, originalTxnType, label) ; log("begin$", txn) ; ReadWrite mode = initialMode(txnType); DatasetGraphTxn dsgTxn = createDSGTxn(dsg, txn, mode); txn.setActiveDataset(dsgTxn) ; dsgTxn.getTransaction().forAllComponents(component->component.begin(dsgTxn.getTransaction())) ; return dsgTxn ; }
@Override public BlockMgr buildBlockMgr(FileSet fileSet, String ext, IndexParams params) { // Find from file ref. FileRef ref = FileRef.create(fileSet, ext) ; BlockMgr baseMgr = blockMgrs.get(ref) ; if ( baseMgr == null ) { //System.out.flush(); System.out.println("No BlockMgr for " + ref+" : "+blockMgrs.keySet()); //throw new TDBException("No BlockMgr for " + ref) ; } BlockMgrJournal blkMgr = new BlockMgrJournal(txn, ref, baseMgr) ; txn.addComponent(blkMgr) ; return blkMgr ; } }
private void prepare() { state = TxnState.PREPARING ; forAllComponents(x->x.commitPrepare(this)); }
@Override public void end() { if ( transaction != null ) transaction.close(); transaction = null; } }
@Override public void abort() { transaction.abort(); }
@Override public void commit() { transaction.commit(); }
private DatasetGraphTDB determineBaseDataset() { // if ( DEBUG ) { // if ( !commitedAwaitingFlush.isEmpty() ) // System.out.print(commitedAwaitingFlush.size()) ; // } else { // System.out.print('_') ; // } DatasetGraphTDB dsg = baseDataset ; // But, if there are pending, committed transactions, use latest. if ( !commitedAwaitingFlush.isEmpty() ) dsg = commitedAwaitingFlush.get(commitedAwaitingFlush.size() - 1).getActiveDataset().getView() ; return dsg ; } private Transaction createTransaction(DatasetGraphTDB dsg, TxnType txnType, TxnType originalTxnType, String label) {
@Override public void transactionPromotes(Transaction txnOld, Transaction txnNew) { // Switch locks. txnOld.getBaseDataset().getLock().leaveCriticalSection() ; txnNew.getBaseDataset().getLock().enterCriticalSection(Lock.READ) ; }
@Override public ObjectFile buildObjectFile(FileSet fileSet, String ext) { FileRef ref = FileRef.create(fileSet, ext) ; ObjectFile base = objectFiles.get(ref) ; // Just write to the (append only) ObjectFile and manage aborts. ObjectFileTrans objFileTxn = new ObjectFileTrans(txn, base) ; txn.addComponent(objFileTxn); return objFileTxn; } }
private void committed() { forAllComponents(x->x.committed(this)); }