/** * To allow for possible 'read committed' behaviour in some databases, where a node that previously existed during a * transaction can disappear from existence, we treat InvalidNodeRefExceptions as concurrency conditions. */ protected <T2> T2 doInRetryingTransaction(final RetryingTransactionCallback<T2> callback, boolean isReadThrough) { return transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionCallback<T2>() { @Override public T2 execute() throws Throwable { try { return callback.execute(); } catch (InvalidNodeRefException e) { // Turn InvalidNodeRefExceptions into retryable exceptions. throw new ConcurrencyFailureException("Possible cache integrity issue during reindexing", e); } } }, true, isReadThrough); }
public void updateAclMember(AclMemberEntity entity) { ParameterCheck.mandatory("entity", entity); ParameterCheck.mandatory("entity.id", entity.getId()); ParameterCheck.mandatory("entity.version", entity.getVersion()); ParameterCheck.mandatory("entity.aceId", entity.getAceId()); ParameterCheck.mandatory("entity.aclId", entity.getAclId()); ParameterCheck.mandatory("entity.pos", entity.getPos()); int updated = updateAclMemberEntity(entity); if (updated < 1) { aclEntityCache.removeByKey(entity.getId()); throw new ConcurrencyFailureException("AclMemberEntity with ID (" + entity.getId() + ") no longer exists or has been updated concurrently"); } }
public void renameAuthority(String before, String after) { ParameterCheck.mandatory("before", before); ParameterCheck.mandatory("after", after); AuthorityEntity entity = getAuthorityForUpdate(before); if (entity != null) { entity.setAuthority(after); entity.setCrc(CrcHelper.getStringCrcPair(after, 32, true, true).getSecond()); int updated = authorityEntityCache.updateValue(entity.getId(), entity); if (updated < 1) { aclEntityCache.removeByKey(entity.getId()); throw new ConcurrencyFailureException("AuthorityEntity with ID (" + entity.getId() + ") no longer exists or has been updated concurrently"); } } }
@Override protected AuditApplicationEntity updateAuditApplication(AuditApplicationEntity entity) { AuditApplicationEntity updateEntity = new AuditApplicationEntity(); updateEntity.setId(entity.getId()); updateEntity.setVersion(entity.getVersion()); updateEntity.incrementVersion(); updateEntity.setApplicationNameId(entity.getApplicationNameId()); updateEntity.setAuditModelId(entity.getAuditModelId()); updateEntity.setDisabledPathsId(entity.getDisabledPathsId()); int updated = template.update(UPDATE_APPLICATION, updateEntity); if (updated != 1) { // unexpected number of rows affected throw new ConcurrencyFailureException("Incorrect number of rows affected for updateAuditApplication: " + updateEntity + ": expected 1, actual " + updated); } // Done return updateEntity; }
public long getTotalDeltaSize(NodeRef nodeRef, boolean removeDeltas) { long nodeId = getNodeIdNotNull(nodeRef); UsageDeltaEntity entity = selectTotalUsageDeltaSize(nodeId); Long totalSize = entity.getDeltaSize(); // Remove the deltas, making sure that the correct number are removed if (removeDeltas) { int deleted = deleteUsageDeltaEntitiesByNodeId(nodeId); if (entity.getDeltaCount() != null && entity.getDeltaCount().intValue() != deleted) { throw new ConcurrencyFailureException( "The number of usage deltas was " + entity.getDeltaCount() + " but only " + deleted + " were deleted."); } } return (totalSize != null ? totalSize : 0L); }
public void updateNamespace(String oldNamespaceUri, String newNamespaceUri) { ParameterCheck.mandatory("newNamespaceUri", newNamespaceUri); Pair<Long, String> oldEntityPair = getNamespace(oldNamespaceUri); // incl. null check if (oldEntityPair == null) { throw new DataIntegrityViolationException( "Cannot update namespace as it doesn't exist: " + oldNamespaceUri); } // Find the value int updated = namespaceCache.updateValue(oldEntityPair.getFirst(), newNamespaceUri); if (updated != 1) { throw new ConcurrencyFailureException( "Incorrect update count: \n" + " Namespace: " + oldNamespaceUri + "\n" + " Rows Updated: " + updated); } // All the QNames need to be dumped qnameCache.clear(); // Done }
@Override public void deleteQName(QName qname) { if (qname == null) { throw new IllegalArgumentException("QName cannot be null"); } // See if the QName exists Pair<Long, QName> qnamePair = qnameCache.getByValue(qname); if (qnamePair == null) { throw new IllegalArgumentException("Cannot delete QName. QName " + qname + " does not exist"); } // Delete Long qnameId = qnamePair.getFirst(); int deleted = qnameCache.deleteByKey(qnameId); if (deleted != 1) { throw new ConcurrencyFailureException("Failed to delete QName entity " + qnameId); } }
@Override protected LockEntity updateLock(LockEntity lockEntity, String lockToken, long timeToLive) { LockEntity updateLockEntity = new LockEntity(); updateLockEntity.setId(lockEntity.getId()); updateLockEntity.setVersion(lockEntity.getVersion()); updateLockEntity.incrementVersion(); // Increment the version number updateLockEntity.setSharedResourceId(lockEntity.getSharedResourceId()); updateLockEntity.setExclusiveResourceId(lockEntity.getExclusiveResourceId()); updateLockEntity.setLockToken(lockToken == null ? null : lockToken.toLowerCase()); long now = (timeToLive > 0) ? System.currentTimeMillis() : 0L; long exp = (timeToLive > 0) ? (now + timeToLive) : 0L; updateLockEntity.setStartTime(new Long(now)); updateLockEntity.setExpiryTime(new Long(exp)); int updated = template.update(UPDATE_LOCK, updateLockEntity); if (updated != 1) { // unexpected number of rows affected throw new ConcurrencyFailureException("Incorrect number of rows affected for updateLock: " + updateLockEntity + ": expected 1, actual " + updated); } // Done return updateLockEntity; }
@Override public void updateContentData(Long id, ContentData contentData) { if (id == null) { throw new IllegalArgumentException("Cannot look up ContentData by null ID."); } if (contentData == null) { throw new IllegalArgumentException("Cannot update ContentData with a null."); } contentData = sanitizeMimetype(contentData); int updated = contentDataCache.updateValue(id, contentData); if (updated < 1) { throw new ConcurrencyFailureException("ContentData with ID " + id + " not updated"); } }
/** * Check that the retries happening for simple concurrency exceptions */ public void testSuccessWithRetry() { RetryingTransactionCallback<Long> callback = new RetryingTransactionCallback<Long>() { private int maxCalls = 3; private int callCount = 0; public Long execute() throws Throwable { callCount++; Long checkValue = incrementCheckValue(); if (callCount == maxCalls) { return checkValue; } else { throw new ConcurrencyFailureException("Testing"); } } }; long txnValue = txnHelper.doInTransaction(callback); assertEquals("Only one increment expected", 1, txnValue); }
@Override protected DataAccessException doTranslate(String task, String sql, SQLException ex) { String sqlState = getSqlState(ex); if (sqlState != null && sqlState.length() >= 2) { String classCode = sqlState.substring(0, 2); if (logger.isDebugEnabled()) { logger.debug("Extracted SQL state class '" + classCode + "' from value '" + sqlState + "'"); } if (BAD_SQL_GRAMMAR_CODES.contains(classCode)) { return new BadSqlGrammarException(task, sql, ex); } else if (DATA_INTEGRITY_VIOLATION_CODES.contains(classCode)) { return new DataIntegrityViolationException(buildMessage(task, sql, ex), ex); } else if (DATA_ACCESS_RESOURCE_FAILURE_CODES.contains(classCode)) { return new DataAccessResourceFailureException(buildMessage(task, sql, ex), ex); } else if (TRANSIENT_DATA_ACCESS_RESOURCE_CODES.contains(classCode)) { return new TransientDataAccessResourceException(buildMessage(task, sql, ex), ex); } else if (CONCURRENCY_FAILURE_CODES.contains(classCode)) { return new ConcurrencyFailureException(buildMessage(task, sql, ex), ex); } } return null; }
/** * Update an existing content item. * * @param content * content item to update * @return updated content item */ public ContentItem updateContent(ContentItem content) { if (content == null) { throw new IllegalArgumentException("content cannot be null"); } if(THROW_CONCURRENT_EXCEPTION) { throw new ConcurrencyFailureException("fail!"); } Item stored = getStorage().getItemByUid(content.getUid()); if (stored != null && stored != content) { throw new UidInUseException(content.getUid(), "Uid " + content.getUid() + " already in use"); } getStorage().updateItem((Item) content); return content; }
@Override @Transactional @Retryable(include = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void pauseRollout(final Long rolloutId) { final JpaRollout rollout = getRolloutAndThrowExceptionIfNotFound(rolloutId); if (!RolloutStatus.RUNNING.equals(rollout.getStatus())) { throw new RolloutIllegalStateException("Rollout can only be paused in state running but current state is " + rollout.getStatus().name().toLowerCase()); } // setting the complete rollout only in paused state. This is sufficient // due the currently running groups will be completed and new groups are // not started until rollout goes back to running state again. The // periodically check for running rollouts will skip rollouts in pause // state. rollout.setStatus(RolloutStatus.PAUSED); rolloutRepository.save(rollout); }
@Override @Transactional @Retryable(include = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void delete(final Long rolloutId) { final JpaRollout jpaRollout = rolloutRepository.findOne(rolloutId); if (jpaRollout == null) { throw new EntityNotFoundException(Rollout.class, rolloutId); } if (RolloutStatus.DELETING.equals(jpaRollout.getStatus())) { return; } jpaRollout.setStatus(RolloutStatus.DELETING); rolloutRepository.save(jpaRollout); }
/** * Get all orphan messages (messages that were left in ephemeral storage for * a long time), retry if deadlock. * * <p> * Note: http://dev.mysql.com/doc/refman/5.0/en/innodb-deadlocks.html * </p> * <p> * InnoDB uses automatic row-level locking. You can get deadlocks even in * the case of transactions that just insert or delete a single row. That is * because these operations are not really "atomic"; they automatically set * locks on the (possibly several) index records of the row inserted or * deleted. * </p> * * @param thresholdTimestampMs * @param conn * @param numRetries * @param maxRetries * @return * @since 0.2.0 */ protected Collection<? extends IQueueMessage<ID, DATA>> _getOrphanMessagesWithRetries( long thresholdTimestampMs, Connection conn, int numRetries, int maxRetries) { try { jdbcHelper.startTransaction(conn); conn.setTransactionIsolation(transactionIsolationLevel); Collection<? extends IQueueMessage<ID, DATA>> msgs = getOrphanFromEphemeralStorage(conn, thresholdTimestampMs); jdbcHelper.commitTransaction(conn); return msgs; } catch (DaoException de) { if (de.getCause() instanceof ConcurrencyFailureException) { jdbcHelper.rollbackTransaction(conn); if (numRetries > maxRetries) { throw new QueueException(de); } else { return _getOrphanMessagesWithRetries(thresholdTimestampMs, conn, numRetries + 1, maxRetries); } } throw de; } catch (Exception e) { jdbcHelper.rollbackTransaction(conn); throw e instanceof QueueException ? (QueueException) e : new QueueException(e); } }
@Override @Transactional @Retryable(include = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void delete(final Collection<Long> targetIDs) { final List<JpaTarget> targets = targetRepository.findAll(targetIDs); if (targets.size() < targetIDs.size()) { throw new EntityNotFoundException(Target.class, targetIDs, targets.stream().map(Target::getId).collect(Collectors.toList())); } targetRepository.deleteByIdIn(targetIDs); afterCommit.afterCommit(() -> targets.forEach(target -> eventPublisher.publishEvent( new TargetDeletedEvent(tenantAware.getCurrentTenant(), target.getId(), target.getControllerId(), Optional.ofNullable(target.getAddress()).map(URI::toString).orElse(null), JpaTarget.class.getName(), applicationContext.getId())))); }
@Override @Transactional @Retryable(include = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public List<Target> assignTag(final Collection<String> controllerIds, final Long tagId) { final List<JpaTarget> allTargets = targetRepository .findAll(TargetSpecifications.byControllerIdWithTagsInJoin(controllerIds)); if (allTargets.size() < controllerIds.size()) { throw new EntityNotFoundException(Target.class, controllerIds, allTargets.stream().map(Target::getControllerId).collect(Collectors.toList())); } final JpaTargetTag tag = targetTagRepository.findById(tagId) .orElseThrow(() -> new EntityNotFoundException(TargetTag.class, tagId)); allTargets.forEach(target -> target.addTag(tag)); final List<Target> result = Collections .unmodifiableList(allTargets.stream().map(targetRepository::save).collect(Collectors.toList())); // No reason to save the tag entityManager.detach(tag); return result; }
/** * {@inheritDoc} */ @Override protected void _finishWithRetries(Connection conn, IQueueMessage<String, byte[]> msg, int numRetries, int maxRetries) { try { removeFromEphemeralStorage(conn, msg); } catch (DaoException de) { if (de.getCause() instanceof ConcurrencyFailureException) { if (numRetries > maxRetries) { throw new QueueException(de); } else { _finishWithRetries(conn, msg, numRetries + 1, maxRetries); } } throw de; } catch (Exception e) { throw e instanceof QueueException ? (QueueException) e : new QueueException(e); } }
@Override @Transactional @Retryable(include = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSetType assignMandatorySoftwareModuleTypes(final Long dsTypeId, final Collection<Long> softwareModulesTypeIds) { final Collection<JpaSoftwareModuleType> modules = softwareModuleTypeRepository.findAll(softwareModulesTypeIds); if (modules.size() < softwareModulesTypeIds.size()) { throw new EntityNotFoundException(SoftwareModuleType.class, softwareModulesTypeIds, modules.stream().map(SoftwareModuleType::getId).collect(Collectors.toList())); } final JpaDistributionSetType type = findDistributionSetTypeAndThrowExceptionIfNotFound(dsTypeId); checkDistributionSetTypeSoftwareModuleTypesIsAllowedToModify(dsTypeId); modules.forEach(type::addMandatoryModuleType); return distributionSetTypeRepository.save(type); }
@Override @Transactional @Retryable(include = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSet assignSoftwareModules(final Long setId, final Collection<Long> moduleIds) { final Collection<JpaSoftwareModule> modules = softwareModuleRepository.findByIdIn(moduleIds); if (modules.size() < moduleIds.size()) { throw new EntityNotFoundException(SoftwareModule.class, moduleIds, modules.stream().map(SoftwareModule::getId).collect(Collectors.toList())); } checkDistributionSetIsAssignedToTargets(setId); final JpaDistributionSet set = findDistributionSetAndThrowExceptionIfNotFound(setId); modules.forEach(set::addModule); return distributionSetRepository.save(set); }
@Override @Transactional @Retryable(include = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public List<DistributionSetMetadata> createMetaData(final Long dsId, final Collection<MetaData> md) { md.forEach(meta -> checkAndThrowAlreadyIfDistributionSetMetadataExists( new DsMetadataCompositeKey(dsId, meta.getKey()))); final JpaDistributionSet set = touch(dsId); return Collections.unmodifiableList(md.stream() .map(meta -> distributionSetMetadataRepository .save(new JpaDistributionSetMetadata(meta.getKey(), set, meta.getValue()))) .collect(Collectors.toList())); }
@Override @Transactional @Retryable(include = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSetMetadata updateMetaData(final Long dsId, final MetaData md) { // check if exists otherwise throw entity not found exception final JpaDistributionSetMetadata toUpdate = (JpaDistributionSetMetadata) getMetaDataByDistributionSetId(dsId, md.getKey()).orElseThrow( () -> new EntityNotFoundException(DistributionSetMetadata.class, dsId, md.getKey())); toUpdate.setValue(md.getValue()); // touch it to update the lock revision because we are modifying the // DS indirectly touch(dsId); return distributionSetMetadataRepository.save(toUpdate); }
@Override @Transactional @Retryable(include = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public List<DistributionSet> assignTag(final Collection<Long> dsIds, final Long dsTagId) { final List<JpaDistributionSet> allDs = findDistributionSetListWithDetails(dsIds); if (allDs.size() < dsIds.size()) { throw new EntityNotFoundException(DistributionSet.class, dsIds, allDs.stream().map(DistributionSet::getId).collect(Collectors.toList())); } final DistributionSetTag distributionSetTag = distributionSetTagManagement.get(dsTagId) .orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, dsTagId)); allDs.forEach(ds -> ds.addTag(distributionSetTag)); final List<DistributionSet> result = Collections .unmodifiableList(allDs.stream().map(distributionSetRepository::save).collect(Collectors.toList())); // No reason to save the tag entityManager.detach(distributionSetTag); return result; }
@Override @Transactional @Retryable(include = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public DistributionSet unAssignTag(final Long dsId, final Long dsTagId) { final JpaDistributionSet set = (JpaDistributionSet) getWithDetails(dsId) .orElseThrow(() -> new EntityNotFoundException(DistributionSet.class, dsId)); final DistributionSetTag distributionSetTag = distributionSetTagManagement.get(dsTagId) .orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, dsTagId)); set.removeTag(distributionSetTag); final JpaDistributionSet result = distributionSetRepository.save(set); // No reason to save the tag entityManager.detach(distributionSetTag); return result; }
/** * Create new content item. A content item represents a piece of content or * file. * * @param parent * parent collection of content. If null, content is assumed to * live in the top-level user collection * @param content * content to create * @return newly created content */ public ContentItem createContent(CollectionItem parent, ContentItem content) { if (parent == null) { throw new IllegalArgumentException("parent cannot be null"); } if (content == null) { throw new IllegalArgumentException("collection cannot be null"); } if(THROW_CONCURRENT_EXCEPTION) { throw new ConcurrencyFailureException("fail!"); } if (getStorage().getItemByUid(content.getUid()) != null) { throw new UidInUseException(content.getUid(), "Uid " + content.getUid() + " already in use"); } ((MockItem) content).addParent(parent); getStorage().storeItem((Item)content); return content; }
@Override @Transactional @Retryable(include = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Target findOrRegisterTargetIfItDoesNotexist(final String controllerId, final URI address) { final Specification<JpaTarget> spec = (targetRoot, query, cb) -> cb .equal(targetRoot.get(JpaTarget_.controllerId), controllerId); final JpaTarget target = targetRepository.findOne(spec); if (target == null) { final Target result = targetRepository.save((JpaTarget) entityFactory.target().create() .controllerId(controllerId).description("Plug and Play target: " + controllerId).name(controllerId) .status(TargetUpdateStatus.REGISTERED).lastTargetQuery(System.currentTimeMillis()) .address(Optional.ofNullable(address).map(URI::toString).orElse(null)).build()); afterCommit.afterCommit( () -> eventPublisher.publishEvent(new TargetPollEvent(result, applicationContext.getId()))); return result; } return updateTargetStatus(target, address); }
@Override @Transactional(isolation = Isolation.READ_COMMITTED) @Retryable(include = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Action addUpdateActionStatus(final ActionStatusCreate c) { final JpaActionStatusCreate create = (JpaActionStatusCreate) c; final JpaAction action = getActionAndThrowExceptionIfNotFound(create.getActionId()); final JpaActionStatus actionStatus = create.build(); // if action is already closed we accept further status updates if // permitted so by configuration. This is especially useful if the // action status feedback channel order from the device cannot be // guaranteed. However, if an action is closed we do not accept further // close messages. if (actionIsNotActiveButIntermediateFeedbackStillAllowed(actionStatus, action.isActive())) { LOG.debug("Update of actionStatus {} for action {} not possible since action not active anymore.", actionStatus.getStatus(), action.getId()); return action; } return handleAddUpdateActionStatus(actionStatus, action); }
@Override @Transactional @Retryable(include = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public Target updateControllerAttributes(final String controllerId, final Map<String, String> data) { final JpaTarget target = (JpaTarget) targetRepository.findByControllerId(controllerId) .orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId)); target.getControllerAttributes().putAll(data); if (target.getControllerAttributes().size() > quotaManagement.getMaxAttributeEntriesPerTarget()) { throw new QuotaExceededException("Controller attribues", target.getControllerAttributes().size(), quotaManagement.getMaxAttributeEntriesPerTarget()); } target.setRequestControllerAttributes(false); return targetRepository.save(target); }
@Override @Transactional @Retryable(include = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public SoftwareModuleMetadata updateMetaData(final SoftwareModuleMetadataUpdate u) { final GenericSoftwareModuleMetadataUpdate update = (GenericSoftwareModuleMetadataUpdate) u; // check if exists otherwise throw entity not found exception final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) getMetaDataBySoftwareModuleId( update.getSoftwareModuleId(), update.getKey()) .orElseThrow(() -> new EntityNotFoundException(SoftwareModuleMetadata.class, update.getSoftwareModuleId(), update.getKey())); update.getValue().ifPresent(metadata::setValue); update.isTargetVisible().ifPresent(metadata::setTargetVisible); touch(metadata.getSoftwareModule()); return softwareModuleMetadataRepository.save(metadata); }
/** * Retrive a session. There will only exists only ONE open session per * application. This means that the closeSession() MUST be called once a * getSession() has been called, else the system will be blocked! * * @return */ private Session getSession() { // Lock here synchronized (sf) { while (sessionLocked) { try { sf.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); throw new ConcurrencyFailureException( "Session wait got interrupted", e); } } // Create Session interceptor... Session session = sf.openSession(); //sessionLocked = true; return (session); } }
/** * {@inheritDoc} */ @Override protected void _finishWithRetries(Connection conn, IQueueMessage<Long, byte[]> msg, int numRetries, int maxRetries) { try { removeFromEphemeralStorage(conn, msg); } catch (DaoException de) { if (de.getCause() instanceof ConcurrencyFailureException) { if (numRetries > maxRetries) { throw new QueueException(de); } else { _finishWithRetries(conn, msg, numRetries + 1, maxRetries); } } throw de; } catch (Exception e) { throw e instanceof QueueException ? (QueueException) e : new QueueException(e); } }
/** * {@inheritDoc} */ @Override protected boolean _moveFromEphemeralToQueueStorageWithRetries(IQueueMessage<Long, byte[]> msg, Connection conn, int numRetries, int maxRetries) { try { int numRows = getJdbcHelper().execute(conn, SQL_CLEAR_EPHEMERAL_ID, getQueueName(), msg.qId()); return numRows > 0; } catch (DaoException de) { if (de.getCause() instanceof ConcurrencyFailureException) { if (numRetries > maxRetries) { throw new QueueException(de); } else { return _moveFromEphemeralToQueueStorageWithRetries(msg, conn, numRetries + 1, maxRetries); } } throw de; } catch (Exception e) { throw e instanceof QueueException ? (QueueException) e : new QueueException(e); } }
/** * {@inheritDoc} */ protected boolean _requeueSilentWithRetries(Connection conn, IQueueMessage<Long, byte[]> msg, int numRetries, int maxRetries) { try { int numRows = getJdbcHelper().execute(conn, SQL_REQUEUE_SILENT, msg.qId()); return numRows > 0; } catch (DuplicatedValueException dve) { LOGGER.warn(dve.getMessage(), dve); return true; } catch (DaoException de) { if (de.getCause() instanceof DuplicateKeyException) { LOGGER.warn(de.getMessage(), de); return true; } if (de.getCause() instanceof ConcurrencyFailureException) { if (numRetries > maxRetries) { throw new QueueException(de); } else { return _requeueSilentWithRetries(conn, msg, numRetries + 1, maxRetries); } } throw de; } catch (Exception e) { throw e instanceof QueueException ? (QueueException) e : new QueueException(e); } }
/** * {@inheritDoc} */ @Override protected boolean _moveFromEphemeralToQueueStorageWithRetries(IQueueMessage<Long, byte[]> msg, Connection conn, int numRetries, int maxRetries) { try { int numRows = getJdbcHelper().execute(conn, SQL_CLEAR_EPHEMERAL_ID, msg.qId()); return numRows > 0; } catch (DaoException de) { if (de.getCause() instanceof ConcurrencyFailureException) { if (numRetries > maxRetries) { throw new QueueException(de); } else { return _moveFromEphemeralToQueueStorageWithRetries(msg, conn, numRetries + 1, maxRetries); } } throw de; } catch (Exception e) { throw e instanceof QueueException ? (QueueException) e : new QueueException(e); } }
/** * {@inheritDoc} */ @Override protected boolean _moveFromEphemeralToQueueStorageWithRetries(IQueueMessage<String, byte[]> msg, Connection conn, int numRetries, int maxRetries) { try { int numRows = getJdbcHelper().execute(conn, SQL_CLEAR_EPHEMERAL_ID, getQueueName(), msg.qId()); return numRows > 0; } catch (DaoException de) { if (de.getCause() instanceof ConcurrencyFailureException) { if (numRetries > maxRetries) { throw new QueueException(de); } else { return _moveFromEphemeralToQueueStorageWithRetries(msg, conn, numRetries + 1, maxRetries); } } throw de; } catch (Exception e) { throw e instanceof QueueException ? (QueueException) e : new QueueException(e); } }
/** * {@inheritDoc} */ protected boolean _requeueSilentWithRetries(Connection conn, IQueueMessage<String, byte[]> msg, int numRetries, int maxRetries) { try { int numRows = getJdbcHelper().execute(conn, SQL_REQUEUE_SILENT, msg.qId()); return numRows > 0; } catch (DuplicatedValueException dve) { LOGGER.warn(dve.getMessage(), dve); return true; } catch (DaoException de) { if (de.getCause() instanceof DuplicateKeyException) { LOGGER.warn(de.getMessage(), de); return true; } if (de.getCause() instanceof ConcurrencyFailureException) { if (numRetries > maxRetries) { throw new QueueException(de); } else { return _requeueSilentWithRetries(conn, msg, numRetries + 1, maxRetries); } } throw de; } catch (Exception e) { throw e instanceof QueueException ? (QueueException) e : new QueueException(e); } }
@ExceptionHandler(ConcurrencyFailureException.class) @ResponseStatus(HttpStatus.CONFLICT) @ResponseBody public ErrorVM processConcurrencyError(ConcurrencyFailureException ex) { log.debug("Concurrency failure", ex); return new ErrorVM(ErrorConstants.ERR_CONCURRENCY_FAILURE, translate(ErrorConstants.ERR_CONCURRENCY_FAILURE)); }
/** * Gets current version of the passed node reference. The node reference is expected to be the 'live' node. * * This uses the version label as a mechanism for looking up the version node. */ private Pair<Boolean, Version> getCurrentVersionImpl(NodeRef versionHistoryRef, NodeRef nodeRef) { // The noderef should not be a version type node. if (nodeRef.getStoreRef().getIdentifier().contains(Version2Model.STORE_ID)) { throw new IllegalArgumentException("The node reference " + nodeRef + " is pointing to a version node, when a reference to a live node is expected."); } Pair<Boolean, Version> result = null; String versionLabel = (String)this.nodeService.getProperty(nodeRef, ContentModel.PROP_VERSION_LABEL); // Note: resultant list is ordered by (a) explicit index and (b) association creation time List<ChildAssociationRef> versionAssocs = getVersionAssocs(versionHistoryRef, false); // Current version should be head version (since no branching) int versionCount = versionAssocs.size(); for (int i = versionCount; i > 0; i--) { ChildAssociationRef versionAssoc = versionAssocs.get(i-1); String tempLabel = (String)this.dbNodeService.getProperty(versionAssoc.getChildRef(), Version2Model.PROP_QNAME_VERSION_LABEL); if (tempLabel != null && tempLabel.equals(versionLabel) == true) { boolean headVersion = (i == versionCount); if (!headVersion) { throw new ConcurrencyFailureException("Unexpected: current version does not appear to be 1st version in the list ["+versionHistoryRef+", "+nodeRef+"]"); } result = new Pair<Boolean, Version>(headVersion, getVersion(versionAssoc.getChildRef())); break; } } return result; }
/** @inheritDoc */ public void deleteTranslationContainer(NodeRef mlContainerNodeRef) { if (!ContentModel.TYPE_MULTILINGUAL_CONTAINER.equals(nodeService.getType(mlContainerNodeRef))) { throw new IllegalArgumentException( "Node type must be " + ContentModel.TYPE_MULTILINGUAL_CONTAINER); } // get the translations Map<Locale, NodeRef> translations = this.getTranslations(mlContainerNodeRef); // remember the number of childs int translationCount = translations.size(); // remove the translations for(NodeRef translationToRemove : translations.values()) { if (!nodeService.exists(translationToRemove)) { // We've just queried for these throw new ConcurrencyFailureException("Translation has been deleted externally: " + translationToRemove); } nodeService.deleteNode(translationToRemove); } // Keep track of the container for pre-commit deletion TransactionalResourceHelper.getSet(KEY_ML_CONTAINERS_TO_DELETE).add(mlContainerNodeRef); AlfrescoTransactionSupport.bindListener(mlContainerCleaner); // done if (logger.isDebugEnabled()) { logger.debug("ML container removed: \n" + " Container: " + mlContainerNodeRef + "\n" + " Number of translations: " + translationCount); } }