Example usage for org.springframework.transaction TransactionStatus rollbackToSavepoint

List of usage examples for org.springframework.transaction TransactionStatus rollbackToSavepoint

Introduction

In this page you can find the example usage for org.springframework.transaction TransactionStatus rollbackToSavepoint.

Prototype

void rollbackToSavepoint(Object savepoint) throws TransactionException;

Source Link

Document

Roll back to the given savepoint.

Usage

From source file:org.ohmage.query.impl.SurveyUploadQuery.java

@Override
public List<Integer> insertSurveys(final String username, final String client, final String campaignUrn,
        final List<SurveyResponse> surveyUploadList, final Map<UUID, Image> bufferedImageMap,
        final Map<String, Video> videoContentsMap, final Map<String, Audio> audioContentsMap)
        throws DataAccessException {

    List<Integer> duplicateIndexList = new ArrayList<Integer>();
    int numberOfSurveys = surveyUploadList.size();

    // The following variables are used in logging messages when errors occur
    SurveyResponse currentSurveyResponse = null;
    PromptResponse currentPromptResponse = null;
    String currentSql = null;/*from w w w. j a v a  2 s  . c  o  m*/

    List<File> fileList = new LinkedList<File>();

    // Wrap all of the inserts in a transaction 
    DefaultTransactionDefinition def = new DefaultTransactionDefinition();
    def.setName("survey upload");
    DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(getDataSource());
    TransactionStatus status = transactionManager.getTransaction(def); // begin transaction

    // Use a savepoint to handle nested rollbacks if duplicates are found
    Object savepoint = status.createSavepoint();

    try { // handle TransactionExceptions

        for (int surveyIndex = 0; surveyIndex < numberOfSurveys; surveyIndex++) {

            try { // handle DataAccessExceptions

                final SurveyResponse surveyUpload = surveyUploadList.get(surveyIndex);
                currentSurveyResponse = surveyUpload;
                currentSql = SQL_INSERT_SURVEY_RESPONSE;

                KeyHolder idKeyHolder = new GeneratedKeyHolder();

                // First, insert the survey
                getJdbcTemplate().update(new PreparedStatementCreator() {
                    public PreparedStatement createPreparedStatement(Connection connection)
                            throws SQLException {
                        PreparedStatement ps = connection.prepareStatement(SQL_INSERT_SURVEY_RESPONSE,
                                Statement.RETURN_GENERATED_KEYS);

                        String locationString = null;
                        Location location = surveyUpload.getLocation();
                        if (location != null) {
                            try {
                                locationString = location.toJson(false, LocationColumnKey.ALL_COLUMNS)
                                        .toString();
                            } catch (JSONException e) {
                                throw new SQLException(e);
                            } catch (DomainException e) {
                                throw new SQLException(e);
                            }
                        }

                        ps.setString(1, surveyUpload.getSurveyResponseId().toString());
                        ps.setString(2, username);
                        ps.setString(3, campaignUrn);
                        ps.setLong(4, surveyUpload.getTime());
                        ps.setString(5, surveyUpload.getTimezone().getID());
                        ps.setString(6, surveyUpload.getLocationStatus().toString());
                        ps.setString(7, locationString);
                        ps.setString(8, surveyUpload.getSurvey().getId());
                        try {
                            ps.setString(9,
                                    surveyUpload
                                            .toJson(false, false, false, false, true, true, true, true, true,
                                                    false, false, true, true, true, true, false, false)
                                            .toString());
                        } catch (JSONException e) {
                            throw new SQLException("Couldn't create the JSON.", e);
                        } catch (DomainException e) {
                            throw new SQLException("Couldn't create the JSON.", e);
                        }
                        ps.setString(10, client);
                        ps.setTimestamp(11, new Timestamp(System.currentTimeMillis()));
                        try {
                            ps.setString(12, surveyUpload.getLaunchContext().toJson(true).toString());
                        } catch (JSONException e) {
                            throw new SQLException("Couldn't create the JSON.", e);
                        }
                        try {
                            ps.setString(13, PreferenceCache.instance()
                                    .lookup(PreferenceCache.KEY_DEFAULT_SURVEY_RESPONSE_SHARING_STATE));
                        } catch (CacheMissException e) {
                            throw new SQLException("Error reading from the cache.", e);
                        }
                        return ps;
                    }
                }, idKeyHolder);

                savepoint = status.createSavepoint();

                final Number surveyResponseId = idKeyHolder.getKey(); // the primary key on the survey_response table for the 
                                                                      // just-inserted survey
                currentSql = SQL_INSERT_PROMPT_RESPONSE;

                // Now insert each prompt response from the survey
                Collection<Response> promptUploadList = surveyUpload.getResponses().values();

                createPromptResponse(username, client, surveyResponseId, fileList, promptUploadList, null,
                        bufferedImageMap, videoContentsMap, audioContentsMap, transactionManager, status);

            } catch (DataIntegrityViolationException dive) { // a unique index exists only on the survey_response table

                if (isDuplicate(dive)) {

                    LOGGER.debug("Found a duplicate survey upload message for user " + username);

                    duplicateIndexList.add(surveyIndex);
                    status.rollbackToSavepoint(savepoint);

                } else {

                    // Some other integrity violation occurred - bad!! All 
                    // of the data to be inserted must be validated before 
                    // this query runs so there is either missing validation 
                    // or somehow an auto_incremented key has been duplicated.

                    LOGGER.error("Caught DataAccessException", dive);
                    logErrorDetails(currentSurveyResponse, currentPromptResponse, currentSql, username,
                            campaignUrn);
                    for (File f : fileList) {
                        f.delete();
                    }
                    rollback(transactionManager, status);
                    throw new DataAccessException(dive);
                }

            } catch (org.springframework.dao.DataAccessException dae) {

                // Some other database problem happened that prevented
                // the SQL from completing normally.

                LOGGER.error("caught DataAccessException", dae);
                logErrorDetails(currentSurveyResponse, currentPromptResponse, currentSql, username,
                        campaignUrn);
                for (File f : fileList) {
                    f.delete();
                }
                rollback(transactionManager, status);
                throw new DataAccessException(dae);
            }

        }

        // Finally, commit the transaction
        transactionManager.commit(status);
        LOGGER.info("Completed survey message persistence");
    }

    catch (TransactionException te) {

        LOGGER.error("failed to commit survey upload transaction, attempting to rollback", te);
        rollback(transactionManager, status);
        for (File f : fileList) {
            f.delete();
        }
        logErrorDetails(currentSurveyResponse, currentPromptResponse, currentSql, username, campaignUrn);
        throw new DataAccessException(te);
    }

    LOGGER.info(
            "Finished inserting survey responses and any associated images into the database and the filesystem.");
    return duplicateIndexList;
}

From source file:com.opengamma.masterdb.batch.DbBatchWriter.java

@SuppressWarnings("unchecked")
public synchronized void addJobResultsInTransaction(TransactionStatus transactionStatus, ObjectId runId,
        ViewComputationResultModel resultModel) {
    ArgumentChecker.notNull(runId, "runId");
    ArgumentChecker.notNull(resultModel, "resultModel");

    final long riskRunId = extractOid(runId);
    ArgumentChecker.notNull(riskRunId, "riskRunId");

    Map<ComputeFailureKey, ComputeFailure> computeFailureCache = _computeFailureCacheByRunId.get(riskRunId);
    Map<Pair<Long, Long>, StatusEntry> statusCache = _statusCacheByRunId.get(riskRunId);

    Map<ValueSpecification, BatchResultWriterFailure> errorCache = populateErrorCache(computeFailureCache,
            resultModel.getAllResults());

    RiskRun run = _riskRunsByIds.get(riskRunId);
    if (run.getSnapshotMode().equals(SnapshotMode.WRITE_THROUGH)) {
        addComputedValuesToMarketDataInTransaction(run.getMarketData().getObjectId(),
                resultModel.getAllMarketData());
    }// ww  w.  j a v a 2  s .  com

    for (String calcConfigName : resultModel.getCalculationConfigurationNames()) {
        ViewCalculationResultModel viewCalculationResultModel = resultModel
                .getCalculationResult(calcConfigName);

        final Set<ComputationTargetSpecification> successfulTargets = newHashSet();
        final Set<ComputationTargetSpecification> failedTargets = newHashSet();

        List<SqlParameterSource> targetProperties = newArrayList();
        List<SqlParameterSource> successes = newArrayList();
        List<SqlParameterSource> failures = newArrayList();
        List<SqlParameterSource> failureReasons = newArrayList();

        Instant evalInstant = Instant.now();

        long calcConfId = _calculationConfigurations.get(calcConfigName);

        for (final ComputationTargetSpecification targetSpec : viewCalculationResultModel.getAllTargets()) {
            final long computationTargetId = _computationTargets.get(targetSpec);
            boolean specFailures = false;
            for (final ComputedValueResult computedValue : viewCalculationResultModel
                    .getAllValues(targetSpec)) {
                ResultConverter<Object> resultConverter = null;
                if (!(computedValue.getValue() instanceof MissingValue)) {
                    try {
                        resultConverter = (ResultConverter<Object>) _resultConverterCache
                                .getConverter(computedValue.getValue());
                    } catch (IllegalArgumentException e) {
                        s_logger.info("No converter for value of type " + computedValue.getValue().getClass()
                                + " for " + computedValue.getSpecification());
                    }
                }

                final ValueSpecification specification = computedValue.getSpecification();
                if (!_riskValueSpecifications.containsKey(specification)) {
                    s_logger.error("Unexpected result specification " + specification
                            + ". Result cannot be written. Result value was " + computedValue.getValue());
                    continue;
                }
                final long valueSpecificationId = _riskValueSpecifications.get(specification);
                final long functionUniqueId = getFunctionUniqueIdInTransaction(
                        specification.getFunctionUniqueId()).getId();
                final long computeNodeId = getOrCreateComputeNode(computedValue.getComputeNodeId()).getId();

                if (resultConverter != null
                        && computedValue.getInvocationResult() == InvocationResult.SUCCESS) {
                    s_logger.debug("Writing value {} for value spec {}", computedValue.getValue(),
                            specification);
                    Map<String, Double> valueAsDoublesMap = resultConverter
                            .convert(computedValue.getSpecification().getValueName(), computedValue.getValue());
                    for (Map.Entry<String, Double> valueEntry : valueAsDoublesMap.entrySet()) {
                        final String valueName = valueEntry.getKey();
                        final Double doubleValue = ensureDatabasePrecision(valueEntry.getValue());
                        final long successId = nextId(RSK_SEQUENCE_NAME);
                        successes.add(getSuccessArgs(successId, riskRunId, evalInstant, calcConfId,
                                computationTargetId, valueSpecificationId, functionUniqueId, computeNodeId,
                                valueName, doubleValue));
                    }
                } else {
                    s_logger.info("Writing failure for {} with invocation result {}, {} ",
                            newArray(computedValue.getSpecification(), computedValue.getInvocationResult(),
                                    computedValue.getAggregatedExecutionLog()));
                    specFailures = true;

                    final long failureId = nextId(RSK_SEQUENCE_NAME);
                    failures.add(getFailureArgs(failureId, riskRunId, evalInstant, calcConfId,
                            computationTargetId, valueSpecificationId, functionUniqueId, computeNodeId,
                            specification.getValueName()));

                    BatchResultWriterFailure cachedFailure = errorCache.get(specification);
                    if (cachedFailure != null) {
                        for (long computeFailureId : cachedFailure.getComputeFailureIds()) {
                            ArgumentChecker.notNull(computeFailureId, "computeFailureId");
                            final long failureReasonId = nextId(RSK_SEQUENCE_NAME);
                            failureReasons
                                    .add(getFailureReasonArgs(failureReasonId, failureId, computeFailureId));
                        }
                    }
                }
            }
            StatusEntry.Status status = getStatus(statusCache, calcConfigName, targetSpec);
            if (specFailures || status == StatusEntry.Status.FAILURE) {
                successfulTargets.remove(targetSpec);
                failedTargets.add(targetSpec);
            } else {
                successfulTargets.add(targetSpec);
            }

            // storing target data
            ComputationTarget computationTarget = _computationTargetResolver.resolve(targetSpec,
                    VersionCorrection.LATEST);
            Object targetValue = computationTarget.getValue();
            if (targetValue instanceof Bean) {
                Bean bean = (Bean) targetValue;
                for (String propertyName : bean.propertyNames()) {
                    Property<Object> property = bean.property(propertyName);
                    final long targetPropertyId = nextId(RSK_SEQUENCE_NAME);
                    targetProperties.add(getTargetPropertyArgs(targetPropertyId, computationTargetId,
                            propertyName, property.get() == null ? "NULL" : property.get().toString()));
                }
            }
        }

        if (successes.isEmpty() && failures.isEmpty() && failureReasons.isEmpty() && successfulTargets.isEmpty()
                && failedTargets.isEmpty()) {
            s_logger.debug("Nothing to write to DB for {}", resultModel);
            return;
        }

        Object preSuccessSavepoint = transactionStatus.createSavepoint();
        try {
            getJdbcTemplate().batchUpdate(getElSqlBundle().getSql("InsertRiskSuccess"),
                    successes.toArray(new DbMapSqlParameterSource[successes.size()]));
        } catch (Exception e) {
            s_logger.error("Failed to write successful calculations to batch database. Converting to failures.",
                    e);
            transactionStatus.rollbackToSavepoint(preSuccessSavepoint);
            if (!successes.isEmpty()) {
                String exceptionClass = e.getClass().getName();
                String exceptionMsg = e.getMessage();
                final StringBuilder buffer = new StringBuilder();
                for (StackTraceElement element : e.getStackTrace()) {
                    buffer.append(element.toString()).append("\n");
                }
                final String stackTrace = buffer.toString();
                for (SqlParameterSource success : successes) {
                    failures.add(convertSuccessToFailure(success));
                    final long failureId = getId(success);
                    final long functionId = getFunctionId(success);
                    ComputeFailureKey computeFailureKey = new ComputeFailureKey(String.valueOf(functionId),
                            exceptionClass, exceptionMsg, stackTrace);
                    ComputeFailure computeFailure = getComputeFailureFromDb(computeFailureCache,
                            computeFailureKey);
                    final long failureReasonId = nextId(RSK_SEQUENCE_NAME);
                    failureReasons
                            .add(getFailureReasonArgs(failureReasonId, failureId, computeFailure.getId()));
                }
                failedTargets.addAll(successfulTargets);
                successes.clear();
                successfulTargets.clear();
                targetProperties.clear();
            }
        }
        Object preTargetPropertiesFailureSavepoint = transactionStatus.createSavepoint();
        try {
            getJdbcTemplate().batchUpdate(getElSqlBundle().getSql("InsertTargetProperties"),
                    targetProperties.toArray(new DbMapSqlParameterSource[targetProperties.size()]));
        } catch (Exception e) {
            s_logger.error("Failed to write target properties to batch database", e);
            transactionStatus.rollbackToSavepoint(preTargetPropertiesFailureSavepoint);
        }
        Object preFailureSavepoint = transactionStatus.createSavepoint();
        try {
            getJdbcTemplate().batchUpdate(getElSqlBundle().getSql("InsertRiskFailure"),
                    failures.toArray(new DbMapSqlParameterSource[failures.size()]));
            getJdbcTemplate().batchUpdate(getElSqlBundle().getSql("InsertRiskFailureReason"),
                    failureReasons.toArray(new DbMapSqlParameterSource[failureReasons.size()]));
        } catch (Exception e) {
            s_logger.error("Failed to write failures to batch database", e);
            transactionStatus.rollbackToSavepoint(preFailureSavepoint);
        }

        updateStatusEntries(riskRunId, statusCache, calcConfigName, StatusEntry.Status.SUCCESS,
                successfulTargets);
        updateStatusEntries(riskRunId, statusCache, calcConfigName, StatusEntry.Status.FAILURE, failedTargets);
    }
}

From source file:jp.terasoluna.fw.batch.util.BatchUtil.java

/**
 * ??????//from   w ww  .  jav  a 2 s. co  m
 * @param stat TransactionStatus
 * @param savepoint ?
 * @param log Log
 */
public static void rollbackSavepoint(TransactionStatus stat, Object savepoint, Log log) {
    if (log != null && log.isDebugEnabled()) {
        logDebug(log, LogId.DAL025050, stat);
    }

    stat.rollbackToSavepoint(savepoint);

    if (log != null && log.isDebugEnabled()) {
        logDebug(log, LogId.DAL025051, stat);
    }
}