private void log(String string, int id, int entityHashValue, byte lockMode, ITransactionContext txnContext) { if (!LOGGER.isEnabled(LVL)) { return; } StringBuilder sb = new StringBuilder(); sb.append("{ op : ").append(string); if (id != NIL) { sb.append(" , dataset : ").append(id); } if (entityHashValue != NIL) { sb.append(" , entity : ").append(entityHashValue); } if (lockMode != LockMode.NL) { sb.append(" , mode : ").append(LockMode.toString(lockMode)); } if (txnContext != null) { sb.append(" , txnId : ").append(txnContext.getTxnId()); } sb.append(" , thread : ").append(Thread.currentThread().getName()); sb.append(" }"); LOGGER.log(LVL, sb.toString()); }
@Override public void jobletFinish(JobStatus jobStatus) { try { ITransactionManager txnManager = ((INcApplicationContext) jobletContext.getServiceContext().getApplicationContext()) .getTransactionSubsystem().getTransactionManager(); for (TxnId subTxnId : txnIdMap.values()) { ITransactionContext txnContext = txnManager.getTransactionContext(subTxnId); txnContext.setWriteTxn(transactionalWrite); if (jobStatus != JobStatus.FAILURE) { txnManager.commitTransaction(subTxnId); } else { txnManager.abortTransaction(subTxnId); } } } catch (ACIDException e) { throw new Error(e); } }
@Override public void commitTransaction(TxnId txnId) throws ACIDException { final ITransactionContext txnCtx = getTransactionContext(txnId); try { if (txnCtx.isWriteTxn()) { LogRecord logRecord = new LogRecord(); TransactionUtil.formJobTerminateLogRecord(txnCtx, logRecord, true); txnSubsystem.getLogManager().log(logRecord); txnCtx.setTxnState(ITransactionManager.COMMITTED); } } catch (Exception e) { if (LOGGER.isErrorEnabled()) { LOGGER.error(" caused exception in commit !" + txnCtx.getTxnId()); } throw e; } finally { txnCtx.complete(); txnSubsystem.getLockManager().releaseLocks(txnCtx); txnCtxRepository.remove(txnCtx.getTxnId()); } }
private void requestAbort(ITransactionContext txnContext, String msg) throws ACIDException { txnContext.setTimeout(true); throw new ACIDException( "Transaction " + txnContext.getTxnId() + " should abort (requested by the Lock Manager)" + ":\n" + msg); }
private void validateJob(ITransactionContext txnContext) throws ACIDException { if (txnContext.getTxnState() == ITransactionManager.ABORTED) { throw new ACIDException("" + txnContext.getTxnId() + " is in ABORTED state."); } else if (txnContext.isTimeout()) { requestAbort(txnContext, "timeout"); } }
@Override public void rollbackTransaction(ITransactionContext txnContext) throws ACIDException { long abortedTxnId = txnContext.getTxnId().getId(); long firstLSN = txnContext.getFirstLSN(); throw new ACIDException(e); long lastLSN = txnContext.getLastLSN(); if (LOGGER.isInfoEnabled()) { LOGGER.info("rollbacking transaction log records from " + firstLSN + " to " + lastLSN); LOGGER.info("no need to roll back as there were no operations by the txn " + txnContext.getTxnId()); + ") during abort( " + txnContext.getTxnId() + ")"); throw new ACIDException("IllegalState exception during abort( " + txnContext.getTxnId() + ")");
private void stallAbortTxn(Thread t, ITransactionContext txnCtx, ITransactionSubsystem txnSubsystem, TxnId txnId) throws InterruptedException, HyracksDataException { try { if (txnCtx.isWriteTxn()) { LogRecord logRecord = new LogRecord(); TransactionUtil.formJobTerminateLogRecord(txnCtx, logRecord, false); txnSubsystem.getLogManager().log(logRecord); txnSubsystem.getCheckpointManager().secure(txnId); synchronized (t) { t.notifyAll(); t.wait(); } txnSubsystem.getRecoveryManager().rollbackTransaction(txnCtx); txnCtx.setTxnState(ITransactionManager.ABORTED); } } catch (ACIDException | HyracksDataException e) { String msg = "Could not complete rollback! System is in an inconsistent state"; throw new ACIDException(msg, e); } finally { txnCtx.complete(); txnSubsystem.getLockManager().releaseLocks(txnCtx); txnSubsystem.getCheckpointManager().completed(txnId); } }
IIndexAccessParameters iap = new IndexAccessParameters(modCallback, NoOpOperationCallback.INSTANCE); ILSMIndexAccessor indexAccessor = lsmIndex.createAccessor(iap); txnCtx.setWriteTxn(true); txnCtx.register(metadataIndex.getResourceId(), StoragePathUtil.getPartitionNumFromRelativePath(resourceName), lsmIndex, modCallback, metadataIndex.isPrimaryIndex());
private static ITransactionContext beingTransaction(INcApplicationContext ncAppCtx, ILSMIndex index, long resourceId) { final TxnId txnId = new TxnId(1); final TransactionOptions options = new TransactionOptions(ITransactionManager.AtomicityLevel.ENTITY_LEVEL); final ITransactionManager transactionManager = ncAppCtx.getTransactionSubsystem().getTransactionManager(); final ITransactionContext txnCtx = transactionManager.beginTransaction(txnId, options); txnCtx.register(resourceId, 0, index, NoOpOperationCallback.INSTANCE, true); return txnCtx; }
synchronized void syncAppendToLogTail(ILogRecord logRecord) { if (logRecord.getLogSource() == LogSource.LOCAL && logRecord.getLogType() != LogType.FLUSH && logRecord.getLogType() != LogType.WAIT && logRecord.getLogType() != LogType.WAIT_FOR_FLUSHES) { ITransactionContext txnCtx = logRecord.getTxnCtx(); if (txnCtx.getTxnState() == ITransactionManager.ABORTED && logRecord.getLogType() != LogType.ABORT) { throw new ACIDException( "Aborted txn(" + txnCtx.getTxnId() + ") tried to write non-abort type log record."); } } final int logSize = logRecord.getLogSize(); ensureSpace(logSize); if (logRecord.getLogType() == LogType.FLUSH) { logRecord.setLSN(appendLSN.get()); } appendPage.append(logRecord, appendLSN.get()); if (logRecord.isMarker()) { logRecord.logAppended(appendLSN.get()); } appendLSN.addAndGet(logSize); }
public void afterOperation() { txnCtx.afterOperation(resourceId); } }
@Override public IModificationOperationCallback createModificationOperationCallback(LocalResource resource, IHyracksTaskContext ctx, IOperatorNodePushable operatorNodePushable) throws HyracksDataException { DatasetLocalResource aResource = (DatasetLocalResource) resource.getResource(); ITransactionSubsystem txnSubsystem = txnSubsystemProvider.getTransactionSubsystem(ctx); IResourceLifecycleManager indexLifeCycleManager = txnSubsystem.getApplicationContext().getDatasetLifecycleManager(); ILSMIndex index = (ILSMIndex) indexLifeCycleManager.get(resource.getPath()); if (index == null) { throw new HyracksDataException("Index(id:" + resource.getId() + ") is not registered."); } try { IJobletEventListenerFactory fact = ctx.getJobletContext().getJobletEventListenerFactory(); ITransactionContext txnCtx = txnSubsystem.getTransactionManager() .getTransactionContext(((IJobEventListenerFactory) fact).getTxnId(datasetId)); IModificationOperationCallback modCallback = new UpsertOperationCallback(new DatasetId(datasetId), primaryKeyFields, txnCtx, txnSubsystem.getLockManager(), txnSubsystem, resource.getId(), aResource.getPartition(), resourceType, indexOp); txnCtx.register(resource.getId(), aResource.getPartition(), index, modCallback, true); return modCallback; } catch (ACIDException e) { throw HyracksDataException.create(e); } } }
public static void formJobTerminateLogRecord(ITransactionContext txnCtx, LogRecord logRecord, boolean isCommit) { logRecord.setTxnCtx(txnCtx); TransactionUtil.formJobTerminateLogRecord(logRecord, txnCtx.getTxnId().getId(), isCommit); }
@Override public void abortTransaction(TxnId txnId) throws ACIDException { final ITransactionContext txnCtx = getTransactionContext(txnId); try { if (txnCtx.isWriteTxn()) { LogRecord logRecord = new LogRecord(); TransactionUtil.formJobTerminateLogRecord(txnCtx, logRecord, false); txnSubsystem.getLogManager().log(logRecord); txnSubsystem.getCheckpointManager().secure(txnId); txnSubsystem.getRecoveryManager().rollbackTransaction(txnCtx); txnCtx.setTxnState(ITransactionManager.ABORTED); } } catch (HyracksDataException e) { String msg = "Could not complete rollback! System is in an inconsistent state"; if (LOGGER.isErrorEnabled()) { LOGGER.log(Level.ERROR, msg, e); } throw new ACIDException(msg, e); } finally { txnCtx.complete(); txnSubsystem.getLockManager().releaseLocks(txnCtx); txnCtxRepository.remove(txnCtx.getTxnId()); txnSubsystem.getCheckpointManager().completed(txnId); } }
@Override public IModificationOperationCallback createModificationOperationCallback(LocalResource resource, IHyracksTaskContext ctx, IOperatorNodePushable operatorNodePushable) throws HyracksDataException { ITransactionSubsystem txnSubsystem = txnSubsystemProvider.getTransactionSubsystem(ctx); IResourceLifecycleManager indexLifeCycleManager = txnSubsystem.getApplicationContext().getDatasetLifecycleManager(); ILSMIndex index = (ILSMIndex) indexLifeCycleManager.get(resource.getPath()); if (index == null) { throw new HyracksDataException("Index(id:" + resource.getId() + ") is not registered."); } try { IJobletEventListenerFactory fact = ctx.getJobletContext().getJobletEventListenerFactory(); ITransactionContext txnCtx = txnSubsystem.getTransactionManager() .getTransactionContext(((IJobEventListenerFactory) fact).getTxnId(datasetId)); DatasetLocalResource aResource = (DatasetLocalResource) resource.getResource(); IModificationOperationCallback modCallback = new SecondaryIndexModificationOperationCallback( new DatasetId(datasetId), primaryKeyFields, txnCtx, txnSubsystem.getLockManager(), txnSubsystem, resource.getId(), aResource.getPartition(), resourceType, indexOp); txnCtx.register(resource.getId(), aResource.getPartition(), index, modCallback, false); return modCallback; } catch (ACIDException e) { throw HyracksDataException.create(e); } } }
@Override public void jobletFinish(JobStatus jobStatus) { try { ITransactionManager txnManager = ((INcApplicationContext) jobletContext.getServiceContext().getApplicationContext()) .getTransactionSubsystem().getTransactionManager(); ITransactionContext txnContext = txnManager.getTransactionContext(txnId); txnContext.setWriteTxn(transactionalWrite); if (jobStatus != JobStatus.FAILURE) { txnManager.commitTransaction(txnId); } else { txnManager.abortTransaction(txnId); } } catch (ACIDException e) { throw new Error(e); } }
@Override public void unlock(DatasetId datasetId, int entityHashValue, byte lockMode, ITransactionContext txnContext) throws ACIDException { log("unlock", datasetId.getId(), entityHashValue, lockMode, txnContext); final long txnId = txnContext.getTxnId().getId(); final long jobSlot = txnId2TxnSlotMap.get(txnId); unlock(datasetId.getId(), entityHashValue, lockMode, jobSlot); }
@Override public IModificationOperationCallback createModificationOperationCallback(LocalResource resource, IHyracksTaskContext ctx, IOperatorNodePushable operatorNodePushable) throws HyracksDataException { ITransactionSubsystem txnSubsystem = txnSubsystemProvider.getTransactionSubsystem(ctx); IResourceLifecycleManager<IIndex> indexLifeCycleManager = txnSubsystem.getApplicationContext().getDatasetLifecycleManager(); ILSMIndex index = (ILSMIndex) indexLifeCycleManager.get(resource.getPath()); if (index == null) { throw new HyracksDataException("Index(id:" + resource.getId() + ") is not registered."); } try { IJobletEventListenerFactory fact = ctx.getJobletContext().getJobletEventListenerFactory(); ITransactionContext txnCtx = txnSubsystem.getTransactionManager() .getTransactionContext(((IJobEventListenerFactory) fact).getTxnId(datasetId)); DatasetLocalResource aResource = (DatasetLocalResource) resource.getResource(); IModificationOperationCallback modCallback = new PrimaryIndexModificationOperationCallback( new DatasetId(datasetId), primaryKeyFields, txnCtx, txnSubsystem.getLockManager(), txnSubsystem, resource.getId(), aResource.getPartition(), resourceType, indexOp, operatorNodePushable); txnCtx.register(resource.getId(), aResource.getPartition(), index, modCallback, true); return modCallback; } catch (ACIDException e) { throw HyracksDataException.create(e); } } }
@Override public void open() throws HyracksDataException { try { transactionContext = transactionManager.getTransactionContext(txnId); transactionContext.setWriteTxn(isWriteTransaction); ILogMarkerCallback callback = TaskUtil.get(ILogMarkerCallback.KEY_MARKER_CALLBACK, ctx); logRecord = new LogRecord(callback); if (isSink) { return; } initAccessAppend(ctx); super.open(); } catch (ACIDException e) { throw HyracksDataException.create(e); } }
public static void formMarkerLogRecord(LogRecord logRecord, ITransactionContext txnCtx, int datasetId, int resourcePartition, ByteBuffer marker) { logRecord.setTxnCtx(txnCtx); logRecord.setLogSource(LogSource.LOCAL); logRecord.setLogType(LogType.MARKER); logRecord.setTxnId(txnCtx.getTxnId().getId()); logRecord.setDatasetId(datasetId); logRecord.setResourcePartition(resourcePartition); marker.get(); // read the first byte since it is not part of the marker object logRecord.setMarker(marker); logRecord.computeAndSetLogSize(); } }