use of io.cdap.cdap.spi.data.transaction.TransactionException in project cdap by caskdata.
the class CoreSchedulerService method cleanupJobs.
// Attempts to remove all jobs that are in PENDING_LAUNCH state.
// These are jobs that were about to be launched, but the scheduler shut down or crashed after the job was marked
// PENDING_LAUNCH, but before they were actually launched.
// This should only be called at startup.
private void cleanupJobs() {
try {
TransactionRunners.run(transactionRunner, context -> {
JobQueueTable jobQueue = JobQueueTable.getJobQueue(context, cConf);
try (CloseableIterator<Job> jobIter = jobQueue.fullScan()) {
LOG.info("Cleaning up jobs in state {}.", Job.State.PENDING_LAUNCH);
while (jobIter.hasNext()) {
Job job = jobIter.next();
if (job.getState() == Job.State.PENDING_LAUNCH) {
LOG.warn("Removing job because it was left in state {} from a previous run of the scheduler: {} .", Job.State.PENDING_LAUNCH, job);
jobQueue.deleteJob(job);
}
}
}
}, TransactionException.class);
} catch (TransactionException exception) {
LOG.warn("Failed to cleanup jobs upon startup.", exception);
}
}
use of io.cdap.cdap.spi.data.transaction.TransactionException in project cdap by caskdata.
the class ArtifactStore method write.
/**
* Write the artifact and its metadata to the store. Once added, artifacts cannot be changed unless they are
* snapshot versions.
*
* @param artifactId the id of the artifact to add
* @param artifactMeta the metadata for the artifact
* @param artifactContent the file containing the content of the artifact
* @return detail about the newly added artifact
* @throws ArtifactAlreadyExistsException if a non-snapshot version of the artifact already exists
* @throws IOException if there was an exception persisting the artifact contents to the filesystem,
* of persisting the artifact metadata to the metastore
*/
public ArtifactDetail write(Id.Artifact artifactId, ArtifactMeta artifactMeta, File artifactContent, EntityImpersonator entityImpersonator) throws ArtifactAlreadyExistsException, IOException {
// if we're not a snapshot version, check that the artifact doesn't exist already.
if (!artifactId.getVersion().isSnapshot()) {
TransactionRunners.run(transactionRunner, context -> {
StructuredTable table = getTable(context, StoreDefinition.ArtifactStore.ARTIFACT_DATA_TABLE);
ArtifactCell artifactCell = new ArtifactCell(artifactId);
if (table.read(artifactCell.keys).isPresent()) {
throw new ArtifactAlreadyExistsException(artifactId.toEntityId());
}
}, ArtifactAlreadyExistsException.class, IOException.class);
}
final Location destination;
try {
destination = copyFileToDestination(artifactId, artifactContent, entityImpersonator);
} catch (Exception e) {
Throwables.propagateIfInstanceOf(e, IOException.class);
throw Throwables.propagate(e);
}
// now try and write the metadata for the artifact
try {
transactionRunner.run(context -> {
// we have to check that the metadata doesn't exist again since somebody else may have written
// the artifact while we were copying the artifact to the filesystem.
StructuredTable artifactDataTable = getTable(context, StoreDefinition.ArtifactStore.ARTIFACT_DATA_TABLE);
ArtifactCell artifactCell = new ArtifactCell(artifactId);
Optional<StructuredRow> optional = artifactDataTable.read(artifactCell.keys);
boolean isSnapshot = artifactId.getVersion().isSnapshot();
if (optional.isPresent() && !isSnapshot) {
// non-snapshot artifacts are immutable. If there is existing metadata, stop here.
throw new ArtifactAlreadyExistsException(artifactId.toEntityId());
}
ArtifactData data = new ArtifactData(destination, artifactMeta);
// this means cleaning up the old jar, and deleting plugin and app rows.
if (optional.isPresent()) {
deleteMeta(context, artifactId, GSON.fromJson(optional.get().getString(StoreDefinition.ArtifactStore.ARTIFACT_DATA_FIELD), ArtifactData.class));
}
// write artifact metadata
writeMeta(context, artifactId, data);
});
return new ArtifactDetail(new ArtifactDescriptor(artifactId.getNamespace().getId(), artifactId.toArtifactId(), destination), artifactMeta);
} catch (TransactionException e) {
destination.delete();
// should throw WriteConflictException(artifactId) on transaction conflict
throw TransactionRunners.propagate(e, ArtifactAlreadyExistsException.class, IOException.class);
}
}
use of io.cdap.cdap.spi.data.transaction.TransactionException in project cdap by caskdata.
the class NoSqlTransactionRunner method run.
@Override
public void run(TxRunnable runnable) throws TransactionException {
try {
MetricsContext metricsCollector = metricsCollectionService.getContext(Constants.Metrics.STORAGE_METRICS_TAGS);
transactional.execute(datasetContext -> runnable.run(new NoSqlStructuredTableContext(tableAdmin, datasetContext, metricsCollector, emitTimeMetrics)));
} catch (TransactionFailureException e) {
throw new TransactionException("Failure executing NoSql transaction:", e.getCause() == null ? e : e.getCause());
}
}
use of io.cdap.cdap.spi.data.transaction.TransactionException in project cdap by caskdata.
the class SqlTransactionRunner method run.
@Override
public void run(TxRunnable runnable) throws TransactionException {
Connection connection;
try {
connection = dataSource.getConnection();
} catch (SQLException e) {
throw new TransactionException("Unable to get connection to the sql database", e);
}
try {
MetricsContext metricsCollector = metricsCollectionService.getContext(Constants.Metrics.STORAGE_METRICS_TAGS);
metricsCollector.increment(Constants.Metrics.StructuredTable.TRANSACTION_COUNT, 1L);
connection.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
connection.setAutoCommit(false);
runnable.run(new SqlStructuredTableContext(admin, connection, metricsCollector, emitTimeMetrics, this.scanFetchSize));
connection.commit();
} catch (Exception e) {
Throwable cause = e.getCause();
if (cause instanceof SQLException) {
rollback(connection, new SqlTransactionException((SQLException) cause, e));
}
rollback(connection, new TransactionException("Failed to execute the sql queries.", e));
} finally {
try {
connection.close();
} catch (SQLException e) {
LOG.warn("Failed to close the sql connection after a transaction", e);
}
}
}
Aggregations