use of org.teiid.dqp.service.TransactionService in project teiid by teiid.
the class ForEachRowPlan method nextBatch.
@Override
public TupleBatch nextBatch() throws BlockedException, TeiidComponentException, TeiidProcessingException {
if (planContext != null) {
this.getContext().getTransactionServer().resume(planContext);
}
try {
while (true) {
if (currentTuple == null) {
if (nextTuple != null) {
currentTuple = nextTuple;
} else if (!nextNull) {
currentTuple = tupleSource.nextTuple();
}
if (currentTuple == null) {
if (this.planContext != null) {
TransactionService ts = this.getContext().getTransactionServer();
ts.commit(this.planContext);
this.planContext = null;
}
TupleBatch result = new TupleBatch(1, new List[] { Arrays.asList((int) Math.min(Integer.MAX_VALUE, updateCount)) });
result.setTerminationFlag(true);
return result;
}
}
if (first) {
TransactionContext tc = this.getContext().getTransactionContext();
if (this.planContext == null && tc != null && tc.getTransactionType() == Scope.NONE) {
Boolean txnRequired = rowProcedure.requiresTransaction(false);
boolean start = false;
if (txnRequired == null) {
nextTuple = tupleSource.nextTuple();
if (nextTuple != null) {
start = true;
} else {
nextNull = true;
}
} else if (Boolean.TRUE.equals(txnRequired)) {
start = true;
}
if (start) {
this.getContext().getTransactionServer().begin(tc);
this.planContext = tc;
}
}
first = false;
}
if (this.rowProcessor == null) {
rowProcedure.reset();
CommandContext context = getContext().clone();
this.rowProcessor = new QueryProcessor(rowProcedure, context, this.bufferMgr, this.dataMgr);
Evaluator eval = new Evaluator(lookupMap, dataMgr, context);
for (Map.Entry<ElementSymbol, Expression> entry : this.params.entrySet()) {
Integer index = this.lookupMap.get(entry.getValue());
if (index != null) {
rowProcedure.getCurrentVariableContext().setValue(entry.getKey(), this.currentTuple.get(index));
} else {
rowProcedure.getCurrentVariableContext().setValue(entry.getKey(), eval.evaluate(entry.getValue(), this.currentTuple));
}
}
}
// save the variable context to get the key information
VariableContext vc = rowProcedure.getCurrentVariableContext();
// just getting the next batch is enough
this.rowProcessor.nextBatch();
if (insert) {
assignGeneratedKey(vc);
}
this.rowProcessor.closeProcessing();
this.rowProcessor = null;
this.currentTuple = null;
this.updateCount++;
}
} finally {
if (planContext != null) {
this.getContext().getTransactionServer().suspend(planContext);
}
}
}
use of org.teiid.dqp.service.TransactionService in project teiid by teiid.
the class TestProcErrors method testNestedBeginAtomicException.
@Test
public void testNestedBeginAtomicException() throws Exception {
TransformationMetadata tm = RealMetadataFactory.example1Cached();
String query = "BEGIN atomic\n" + " declare string VARIABLES.RESULT;\n" + " begin atomic select 1/0; exception e end end";
ProcessorPlan plan = getProcedurePlan(query, tm);
// Create expected results
List<?>[] expected = new List[0];
// $NON-NLS-1$
CommandContext context = new CommandContext("pID", null, null, null, 1);
QueryMetadataInterface metadata = new TempMetadataAdapter(tm, new TempMetadataStore());
context.setMetadata(metadata);
TransactionContext tc = new TransactionContext();
Transaction txn = Mockito.mock(Transaction.class);
tc.setTransaction(txn);
tc.setTransactionType(Scope.REQUEST);
TransactionService ts = Mockito.mock(TransactionService.class);
context.setTransactionService(ts);
context.setTransactionContext(tc);
TestProcessor.helpProcess(plan, context, new HardcodedDataManager(), expected);
Mockito.verify(txn, Mockito.times(3)).setRollbackOnly();
}
use of org.teiid.dqp.service.TransactionService in project teiid by teiid.
the class ForEachRowPlan method close.
@Override
public void close() throws TeiidComponentException {
if (this.queryProcessor != null) {
this.queryProcessor.closeProcessing();
if (this.rowProcessor != null) {
this.rowProcessor.closeProcessing();
}
}
if (this.planContext != null) {
TransactionService ts = this.getContext().getTransactionServer();
try {
ts.resume(planContext);
ts.rollback(planContext);
this.planContext = null;
} catch (XATransactionException e) {
throw new TeiidComponentException(QueryPlugin.Event.TEIID30165, e);
}
}
}
use of org.teiid.dqp.service.TransactionService in project teiid by teiid.
the class ProcedurePlan method pop.
/**
* @param success
* @throws TeiidComponentException
* @throws XATransactionException
*/
public void pop(boolean success) throws TeiidComponentException {
this.evaluator.close();
Program program = this.programs.pop();
VariableContext vc = this.currentVarContext;
VariableContext cs = this.cursorStates;
try {
this.currentVarContext = this.currentVarContext.getParentContext();
this.cursorStates = this.cursorStates.getParentContext();
TempTableStore tempTableStore = program.getTempTableStore();
this.getContext().setTempTableStore(tempTableStore.getParentTempTableStore());
tempTableStore.removeTempTables();
if (program.startedTxn()) {
TransactionService ts = this.getContext().getTransactionServer();
TransactionContext tc = this.blockContext;
this.blockContext = null;
try {
ts.resume(tc);
for (WeakReference<DataTierTupleSource> ref : txnTupleSources) {
DataTierTupleSource dtts = ref.get();
if (dtts != null) {
dtts.fullyCloseSource();
}
}
this.txnTupleSources.clear();
if (success) {
ts.commit(tc);
} else {
ts.rollback(tc);
}
} catch (XATransactionException e) {
throw new TeiidComponentException(QueryPlugin.Event.TEIID30165, e);
}
}
} finally {
removeAllCursors(cs);
}
}
use of org.teiid.dqp.service.TransactionService in project teiid by teiid.
the class BatchedUpdatePlan method nextBatch.
/**
* @see org.teiid.query.processor.ProcessorPlan#nextBatch()
* @since 4.2
*/
public TupleBatch nextBatch() throws BlockedException, TeiidComponentException, TeiidProcessingException {
for (; planIndex < updatePlans.length && (getContext() == null || getContext().getBatchUpdateException() == null); ) {
try {
if (!planOpened[planIndex]) {
// Open the plan only once
/* Defect 16166
* Some commands in a batch may depend on updates by previous commands in the same batch. A call
* to open() usually submits an atomic command, so calling open() on all the child plans at the same time
* will mean that the datasource may not be in the state expected by a later command within the batch. So,
* for a batch of commands, we only open() a later plan when we are finished with the previous plan to
* guarantee that the commands in the previous plan are completed before the commands in any subsequent
* plans are executed.
*/
openPlan();
} else if (this.planContexts[planIndex] != null) {
this.getContext().getTransactionServer().resume(this.planContexts[planIndex]);
}
// Execute nextBatch() on each plan in sequence
TupleBatch nextBatch = null;
do {
// Can throw BlockedException
nextBatch = updatePlans[planIndex].nextBatch();
List<List<?>> currentBatch = nextBatch.getTuples();
for (int i = 0; i < currentBatch.size(); i++, commandIndex++) {
updateCounts[commandIndex] = currentBatch.get(i);
}
} while (!nextBatch.getTerminationFlag());
// since we are done with the plan explicitly close it.
updatePlans[planIndex].close();
if (this.planContexts[planIndex] != null) {
TransactionService ts = this.getContext().getTransactionServer();
ts.commit(this.planContexts[planIndex]);
this.planContexts[planIndex] = null;
}
planIndex++;
} catch (BlockedException e) {
throw e;
} catch (TeiidComponentException | TeiidProcessingException e) {
if (singleResult) {
throw e;
}
Throwable cause = e;
if (e.getCause() instanceof TranslatorBatchException) {
TranslatorBatchException tbe = (TranslatorBatchException) e.getCause();
for (int i = 0; i < tbe.getUpdateCounts().length; i++) {
updateCounts[commandIndex++] = Arrays.asList(tbe.getUpdateCounts()[i]);
}
}
updateCounts = Arrays.copyOf(updateCounts, commandIndex);
getContext().setBatchUpdateException(cause);
} finally {
if (planIndex < updatePlans.length && this.planContexts[planIndex] != null) {
this.getContext().getTransactionServer().suspend(this.planContexts[planIndex]);
}
}
}
if (singleResult) {
long result = 0;
for (int i = 0; i < updateCounts.length; i++) {
int value = (Integer) updateCounts[i].get(0);
if (value == Statement.EXECUTE_FAILED) {
// the batch results rather than throwing an exception
throw new TeiidProcessingException(QueryPlugin.Event.TEIID31199, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31198));
}
if (value > 0) {
result += value;
}
}
TupleBatch batch = new TupleBatch(1, new List<?>[] { Arrays.asList((int) Math.min(Integer.MAX_VALUE, result)) });
batch.setTerminationFlag(true);
return batch;
}
// Add tuples to current batch
TupleBatch batch = new TupleBatch(1, updateCounts);
batch.setTerminationFlag(true);
return batch;
}
Aggregations