Search in sources :

Example 1 with TransactionException

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);
    }
}
Also used : TransactionException(io.cdap.cdap.spi.data.transaction.TransactionException) JobQueueTable(io.cdap.cdap.internal.app.runtime.schedule.queue.JobQueueTable) Job(io.cdap.cdap.internal.app.runtime.schedule.queue.Job)

Example 2 with TransactionException

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);
    }
}
Also used : StructuredTable(io.cdap.cdap.spi.data.StructuredTable) StructuredRow(io.cdap.cdap.spi.data.StructuredRow) IOException(java.io.IOException) ArtifactAlreadyExistsException(io.cdap.cdap.common.ArtifactAlreadyExistsException) TransactionException(io.cdap.cdap.spi.data.transaction.TransactionException) PluginNotExistsException(io.cdap.cdap.internal.app.runtime.plugin.PluginNotExistsException) IOException(java.io.IOException) TableNotFoundException(io.cdap.cdap.spi.data.TableNotFoundException) ArtifactNotFoundException(io.cdap.cdap.common.ArtifactNotFoundException) TransactionException(io.cdap.cdap.spi.data.transaction.TransactionException) ArtifactAlreadyExistsException(io.cdap.cdap.common.ArtifactAlreadyExistsException) Location(org.apache.twill.filesystem.Location)

Example 3 with TransactionException

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());
    }
}
Also used : TransactionFailureException(org.apache.tephra.TransactionFailureException) TransactionException(io.cdap.cdap.spi.data.transaction.TransactionException) MetricsContext(io.cdap.cdap.api.metrics.MetricsContext)

Example 4 with TransactionException

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);
        }
    }
}
Also used : TransactionException(io.cdap.cdap.spi.data.transaction.TransactionException) SQLException(java.sql.SQLException) MetricsContext(io.cdap.cdap.api.metrics.MetricsContext) Connection(java.sql.Connection) TransactionException(io.cdap.cdap.spi.data.transaction.TransactionException) SQLException(java.sql.SQLException)

Aggregations

TransactionException (io.cdap.cdap.spi.data.transaction.TransactionException)4 MetricsContext (io.cdap.cdap.api.metrics.MetricsContext)2 ArtifactAlreadyExistsException (io.cdap.cdap.common.ArtifactAlreadyExistsException)1 ArtifactNotFoundException (io.cdap.cdap.common.ArtifactNotFoundException)1 PluginNotExistsException (io.cdap.cdap.internal.app.runtime.plugin.PluginNotExistsException)1 Job (io.cdap.cdap.internal.app.runtime.schedule.queue.Job)1 JobQueueTable (io.cdap.cdap.internal.app.runtime.schedule.queue.JobQueueTable)1 StructuredRow (io.cdap.cdap.spi.data.StructuredRow)1 StructuredTable (io.cdap.cdap.spi.data.StructuredTable)1 TableNotFoundException (io.cdap.cdap.spi.data.TableNotFoundException)1 IOException (java.io.IOException)1 Connection (java.sql.Connection)1 SQLException (java.sql.SQLException)1 TransactionFailureException (org.apache.tephra.TransactionFailureException)1 Location (org.apache.twill.filesystem.Location)1