@Override public void afterRead(Long id) { int count = jdbcTemplate.update("UPDATE BATCH_STAGING SET PROCESSED=? WHERE ID=? AND PROCESSED=?", StagingItemWriter.DONE, id, StagingItemWriter.NEW); if (count != 1) { throw new OptimisticLockingFailureException("The staging record with ID=" + id + " was updated concurrently when trying to mark as complete (updated " + count + " records."); } }
protected ScimUser deleteUser(ScimUser user, int version, String zoneId) { int updated = deleteUser(user.getId(), version, zoneId); if (updated == 0) { throw new OptimisticLockingFailureException(String.format( "Attempt to update a user (%s) with wrong version: expected=%d but found=%d", user.getId(), version, version)); } return user; }
@Override public ScimUser verifyUser(String id, int version, String zoneId) throws ScimResourceNotFoundException, InvalidScimResourceException { logger.debug("Verifying user: " + id); int updated; if (version < 0) { // Ignore updated = jdbcTemplate.update(VERIFY_USER_SQL, true, id, zoneId); } else { updated = jdbcTemplate.update(VERIFY_USER_SQL + " and version=?", true, id, zoneId, version); } ScimUser user = retrieve(id, zoneId); if (updated == 0) { throw new OptimisticLockingFailureException(String.format( "Attempt to update a user (%s) with wrong version: expected=%d but found=%d", user.getId(), user.getVersion(), version)); } if (updated > 1) { throw new IncorrectResultSizeDataAccessException(1); } return user; }
@Override public void updateJobExecution(JobExecution jobExecution) { Long id = jobExecution.getId(); Assert.notNull(id, "JobExecution is expected to have an id (should be saved already)"); JobExecution persistedExecution = executionsById.get(id); Assert.notNull(persistedExecution, "JobExecution must already be saved"); synchronized (jobExecution) { if (!persistedExecution.getVersion().equals(jobExecution.getVersion())) { throw new OptimisticLockingFailureException("Attempt to update job execution id=" + id + " with wrong version (" + jobExecution.getVersion() + "), where current version is " + persistedExecution.getVersion()); } jobExecution.incrementVersion(); executionsById.put(id, copy(jobExecution)); } }
private ScimUser deactivateUser(ScimUser user, int version, String zoneId) { logger.debug("Deactivating user: " + user.getId()); int updated; if (version < 0) { // Ignore updated = jdbcTemplate.update(DEACTIVATE_USER_SQL, false, user.getId(), zoneId); } else { updated = jdbcTemplate.update(DEACTIVATE_USER_SQL + " and version=?", false, user.getId(), zoneId, version); } if (updated == 0) { throw new OptimisticLockingFailureException(String.format( "Attempt to update a user (%s) with wrong version: expected=%d but found=%d", user.getId(), user.getVersion(), version)); } if (updated > 1) { throw new IncorrectResultSizeDataAccessException(1); } user.setActive(false); return user; }
/** * Use the technical identifier to mark the input row as processed and * return unwrapped item. */ @Override public T process(ProcessIndicatorItemWrapper<T> wrapper) throws Exception { int count = jdbcTemplate.update("UPDATE BATCH_STAGING SET PROCESSED=? WHERE ID=? AND PROCESSED=?", StagingItemWriter.DONE, wrapper.getId(), StagingItemWriter.NEW); if (count != 1) { throw new OptimisticLockingFailureException("The staging record with ID=" + wrapper.getId() + " was updated concurrently when trying to mark as complete (updated " + count + " records."); } return wrapper.getItem(); }
@Override public void updateStepExecution(StepExecution stepExecution) { Assert.notNull(stepExecution.getJobExecutionId(), "jobExecution id is null"); Map<Long, StepExecution> executions = executionsByJobExecutionId.get(stepExecution.getJobExecutionId()); Assert.notNull(executions, "step executions for given job execution are expected to be already saved"); final StepExecution persistedExecution = executionsByStepExecutionId.get(stepExecution.getId()); Assert.notNull(persistedExecution, "step execution is expected to be already saved"); synchronized (stepExecution) { if (!persistedExecution.getVersion().equals(stepExecution.getVersion())) { throw new OptimisticLockingFailureException("Attempt to update step execution id=" + stepExecution.getId() + " with wrong version (" + stepExecution.getVersion() + "), where current version is " + persistedExecution.getVersion()); } stepExecution.incrementVersion(); StepExecution copy = new StepExecution(stepExecution.getStepName(), stepExecution.getJobExecution()); copy(stepExecution, copy); executions.put(stepExecution.getId(), copy); executionsByStepExecutionId.put(stepExecution.getId(), copy); } }
ScimUser result = retrieve(id, zoneId); if (updated == 0) { throw new OptimisticLockingFailureException(String.format( "Attempt to update a user (%s) with wrong version: expected=%d but found=%d", id, result.getVersion(), user.getVersion()));
@Override public String doInTransaction(TransactionStatus status) { assertTrue(TransactionSynchronizationManager.isSynchronizationActive()); assertTrue(TransactionSynchronizationManager.isActualTransactionActive()); assertFalse(TransactionSynchronizationManager.isCurrentTransactionReadOnly()); throw new OptimisticLockingFailureException(""); } });
: updateMapper.getMappedObject(update.getUpdateObject(), entity); if (containsVersionProperty(queryObj, entity)) throw new OptimisticLockingFailureException("Optimistic lock exception on saving entity: " + updateObj.toString() + " to collection " + collectionName);
@SuppressWarnings("unchecked") private <T> T doSaveVersioned(AdaptibleEntity<T> source, String collectionName) { if (source.isNew()) { return (T) doInsert(collectionName, source.getBean(), this.mongoConverter); } // Create query for entity with the id and old version Query query = source.getQueryForVersion(); // Bump version number T toSave = source.incrementVersion(); toSave = maybeEmitEvent(new BeforeConvertEvent<T>(toSave, collectionName)).getSource(); source.assertUpdateableIdIfNotSet(); MappedDocument mapped = source.toMappedDocument(mongoConverter); maybeEmitEvent(new BeforeSaveEvent<>(toSave, mapped.getDocument(), collectionName)); UpdateDefinition update = mapped.updateWithoutId(); UpdateResult result = doUpdate(collectionName, query, update, toSave.getClass(), false, false); if (result.getModifiedCount() == 0) { throw new OptimisticLockingFailureException( String.format("Cannot save entity %s with version %s to collection %s. Has it been modified meanwhile?", source.getId(), source.getVersion(), collectionName)); } maybeEmitEvent(new AfterSaveEvent<>(toSave, mapped.getDocument(), collectionName)); return toSave; }
int currentVersion = getJdbcTemplate().queryForObject(getQuery(CURRENT_VERSION_JOB_EXECUTION), Integer.class, new Object[] { jobExecution.getId() }); throw new OptimisticLockingFailureException("Attempt to update job execution id=" + jobExecution.getId() + " with wrong version (" + jobExecution.getVersion() + "), where current version is " + currentVersion);
@Test public void jtaTransactionManagerWithExistingTransactionAndCommitException() throws Exception { UserTransaction ut = mock(UserTransaction.class); given(ut.getStatus()).willReturn(Status.STATUS_ACTIVE); final TransactionSynchronization synch = mock(TransactionSynchronization.class); willThrow(new OptimisticLockingFailureException("")).given(synch).beforeCommit(false); JtaTransactionManager ptm = newJtaTransactionManager(ut); TransactionTemplate tt = new TransactionTemplate(ptm); assertFalse(TransactionSynchronizationManager.isSynchronizationActive()); try { tt.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { assertTrue(TransactionSynchronizationManager.isSynchronizationActive()); TransactionSynchronizationManager.registerSynchronization(synch); } }); fail("Should have thrown OptimisticLockingFailureException"); } catch (OptimisticLockingFailureException ex) { // expected } assertFalse(TransactionSynchronizationManager.isSynchronizationActive()); verify(ut).setRollbackOnly(); verify(synch).beforeCompletion(); verify(synch).afterCompletion(TransactionSynchronization.STATUS_UNKNOWN); }
@Test public void transactionExceptionPropagatedWithCallbackPreference() throws Throwable { TransactionAttribute txatt = new DefaultTransactionAttribute(); MapTransactionAttributeSource tas = new MapTransactionAttributeSource(); tas.register(exceptionalMethod, txatt); MockCallbackPreferringTransactionManager ptm = new MockCallbackPreferringTransactionManager(); TestBean tb = new TestBean(); ITestBean itb = (ITestBean) advised(tb, ptm, tas); checkTransactionStatus(false); try { itb.exceptional(new OptimisticLockingFailureException("")); fail("Should have thrown OptimisticLockingFailureException"); } catch (OptimisticLockingFailureException ex) { // expected } checkTransactionStatus(false); assertSame(txatt, ptm.getDefinition()); assertFalse(ptm.getStatus().isRollbackOnly()); }
@Test public void exceptionTranslationWithTranslation() { MapPersistenceExceptionTranslator mpet1 = new MapPersistenceExceptionTranslator(); RuntimeException in1 = new RuntimeException("in"); InvalidDataAccessApiUsageException out1 = new InvalidDataAccessApiUsageException("out"); InvalidDataAccessApiUsageException out2 = new InvalidDataAccessApiUsageException("out"); mpet1.addTranslation(in1, out1); ChainedPersistenceExceptionTranslator chainedPet1 = new ChainedPersistenceExceptionTranslator(); assertSame("Should not translate yet", in1, DataAccessUtils.translateIfNecessary(in1, chainedPet1)); chainedPet1.addDelegate(mpet1); assertSame("Should now translate", out1, DataAccessUtils.translateIfNecessary(in1, chainedPet1)); // Now add a new translator and verify it wins MapPersistenceExceptionTranslator mpet2 = new MapPersistenceExceptionTranslator(); mpet2.addTranslation(in1, out2); chainedPet1.addDelegate(mpet2); assertSame("Should still translate the same due to ordering", out1, DataAccessUtils.translateIfNecessary(in1, chainedPet1)); ChainedPersistenceExceptionTranslator chainedPet2 = new ChainedPersistenceExceptionTranslator(); chainedPet2.addDelegate(mpet2); chainedPet2.addDelegate(mpet1); assertSame("Should translate differently due to ordering", out2, DataAccessUtils.translateIfNecessary(in1, chainedPet2)); RuntimeException in2 = new RuntimeException("in2"); OptimisticLockingFailureException out3 = new OptimisticLockingFailureException("out2"); assertNull(chainedPet2.translateExceptionIfPossible(in2)); MapPersistenceExceptionTranslator mpet3 = new MapPersistenceExceptionTranslator(); mpet3.addTranslation(in2, out3); chainedPet2.addDelegate(mpet3); assertSame(out3, chainedPet2.translateExceptionIfPossible(in2)); }
int currentVersion = getJdbcTemplate().queryForObject(getQuery(CURRENT_VERSION_STEP_EXECUTION), new Object[] { stepExecution.getId() }, Integer.class); throw new OptimisticLockingFailureException("Attempt to update step execution id=" + stepExecution.getId() + " with wrong version (" + stepExecution.getVersion() + "), where current version is " + currentVersion);
: updateMapper.getMappedObject(update.getUpdateObject(), entity); if (containsVersionProperty(queryObj, entity)) throw new OptimisticLockingFailureException("Optimistic lock exception on saving entity: " + updateObj.toString() + " to collection " + collectionName);
@SuppressWarnings("unchecked") private <T> T doSaveVersioned(AdaptibleEntity<T> source, String collectionName) { if (source.isNew()) { return (T) doInsert(collectionName, source.getBean(), this.mongoConverter); } // Create query for entity with the id and old version Query query = source.getQueryForVersion(); // Bump version number T toSave = source.incrementVersion(); toSave = maybeEmitEvent(new BeforeConvertEvent<T>(toSave, collectionName)).getSource(); source.assertUpdateableIdIfNotSet(); MappedDocument mapped = source.toMappedDocument(mongoConverter); maybeEmitEvent(new BeforeSaveEvent<>(toSave, mapped.getDocument(), collectionName)); UpdateDefinition update = mapped.updateWithoutId(); UpdateResult result = doUpdate(collectionName, query, update, toSave.getClass(), false, false); if (result.getModifiedCount() == 0) { throw new OptimisticLockingFailureException( String.format("Cannot save entity %s with version %s to collection %s. Has it been modified meanwhile?", source.getId(), source.getVersion(), collectionName)); } maybeEmitEvent(new AfterSaveEvent<>(toSave, mapped.getDocument(), collectionName)); return toSave; }
@Transactional public void startShipping(StartShippingRequest req) { Order order = orderRepository.findById(new OrderNo(req.getOrderNumber())); checkNoOrder(order); if (!order.matchVersion(req.getVersion())) { // throw new VersionConflictException(); throw new OptimisticLockingFailureException("version conflict"); } order.startShipping(); }
public void storeEventsIntoStream(UUID streamId, long expectedVersion, EventSource<E> source) { EventStream<E> stream = getStream(streamId); if (stream.getVersion() != expectedVersion) { throw new OptimisticLockingFailureException("stream " + streamId + ", actual version: " + stream.getVersion() + ", expected version: " + expectedVersion); } stream.setVersion(source.getVersion()); stream.setTimestamp(source.getTimestamp()); stream.addEvents(source.getEvents()); }