下面列出了org.hibernate.NonUniqueObjectException#org.springframework.orm.ObjectOptimisticLockingFailureException 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private GuildConfig updateIfRequred(Guild guild, GuildConfig config) {
try {
boolean shouldSave = false;
if (!Objects.equals(config.getName(), guild.getName())) {
config.setName(guild.getName());
shouldSave = true;
}
if (!Objects.equals(config.getIconUrl(), guild.getIconUrl())) {
config.setIconUrl(guild.getIconUrl());
shouldSave = true;
}
if (shouldSave) {
configService.save(config);
}
} catch (ObjectOptimisticLockingFailureException e) {
// it's ok to ignore optlock here, anyway it will be updated later
}
return config;
}
private LocalMember updateIfRequired(Member member, LocalMember localMember) {
try {
boolean shouldSave = false;
if (localMember.getId() == null) {
shouldSave = true;
}
if (member != null) {
// do not force update effective name here, it will be updated using listener
updateIfRequired(member.getUser(), localMember.getUser());
}
if (shouldSave) {
memberService.save(localMember);
}
} catch (ObjectOptimisticLockingFailureException e) {
// it's ok to ignore optlock here, anyway it will be updated later
}
return localMember;
}
private void loopListeners(GenericEvent event) {
if (event instanceof GuildMessageReceivedEvent) {
dispatchChain(GuildMessageReceivedEvent.class, (GuildMessageReceivedEvent) event);
}
for (EventListener listener : listeners) {
try {
listener.onEvent(event);
} catch (ObjectOptimisticLockingFailureException e) {
log.warn("[{}] optimistic lock happened for {}#{} while handling {}",
listener.getClass().getSimpleName(),
e.getPersistentClassName(),
e.getIdentifier(),
event);
} catch (Throwable throwable) {
log.error("[{}] had an uncaught exception for handling {}",
listener.getClass().getSimpleName(),
event,
throwable);
}
}
}
@Test
public void testRetry() {
when(mockLifecycleRepository.save(any(LifecycleEntity.class)))
// first time throw an exception
.thenThrow(new ObjectOptimisticLockingFailureException(ApplicationEntity.class, "foobar"))
// second time throw another exception
.thenThrow(new OptimisticLockException("Oops"))
// third time thrwo another exception
.thenThrow(new DataIntegrityViolationException("Hoppla"))
// Last time succeed.
.thenReturn(lifecycle);
assertThat(service.saveLifecycle(application, version, lifecycle)).isSameAs(lifecycle);
verify(mockApplicationRepository, times(4)).findByName(eq("foobar"));
verify(mockVersionRepository, times(4)).findByName(eq("1.0"));
verify(mockLifecycleRepository, times(4)).save(any(LifecycleEntity.class));
}
/**
* 拦截乐观锁失败异常
*
* @param ex
* @return
*/
@ResponseBody
@ExceptionHandler(value = ObjectOptimisticLockingFailureException.class)
public MessageResult myErrorHandler(ObjectOptimisticLockingFailureException ex) {
ex.printStackTrace();
log.info(">>>拦截乐观锁失败异常>>",ex);
MessageResult result = MessageResult.error(6000, "数据过期,请刷新重试");
return result;
}
/**
* 拦截乐观锁失败异常
*
* @param ex
* @return
*/
@ResponseBody
@ExceptionHandler(value = ObjectOptimisticLockingFailureException.class)
public MessageResult myErrorHandler(ObjectOptimisticLockingFailureException ex) {
ex.printStackTrace();
log.info(">>>拦截乐观锁失败异常>>",ex);
MessageResult result = MessageResult.error(6000, "数据过期,请刷新重试");
return result;
}
private LocalUser updateIfRequired(User user, LocalUser localUser) {
try {
boolean shouldSave = false;
if (localUser.getId() == null) {
shouldSave = true;
}
if (user != null) {
if (!Objects.equals(user.getName(), localUser.getName())) {
localUser.setName(user.getName());
shouldSave = true;
}
if (!Objects.equals(user.getDiscriminator(), localUser.getDiscriminator())) {
localUser.setDiscriminator(user.getDiscriminator());
shouldSave = true;
}
if (!Objects.equals(user.getAvatarUrl(), localUser.getAvatarUrl())) {
localUser.setAvatarUrl(user.getAvatarUrl());
shouldSave = true;
}
}
if (shouldSave) {
localUser = userService.save(localUser);
}
} catch (ObjectOptimisticLockingFailureException e) {
// it's ok to ignore optlock here, anyway it will be updated later
}
return localUser;
}
/**
* Default an unique constructor. It must provide valid values for Controller, record and model. Also, it receives
* the {@link ObjectOptimisticLockingFailureException} that has thrown this exception to maintain all the provided
* information.
*
* @param manager
* @param record
* @param model
* @param ex
*/
public <T> ConcurrencyException( ConcurrencyManager<T> manager, T record, Model model,
ObjectOptimisticLockingFailureException ex )
{
super( ex.getPersistentClass(), ex.getIdentifier(), ex.getMessage(), ex.getCause() );
Assert.notNull( manager, "ERROR: You must provide a not null controller to throw this exception." );
Assert.notNull( record, "ERROR: You must provide a not null record to throw this exception." );
Assert.notNull( model, "ERROR: You must provide a not null model to throw this exception." );
this.manager = manager;
this.record = record;
this.model = model;
}
/**
* Executes the provided action. If something goes wrong and a {@link ConcurrencyException} appears during
* the process, it delegates in the provided {@link ConcurrencyManager} to manage the concurrency behaviour.
*
* @param action The action that should be executed and that could produce a Concurrency Exception.
* @return An object with the same type as the specified in the ConcurrencyTemplate constructor
* @throws ConcurrencyTemplateException if some exception different of {@link ObjectOptimisticLockingFailureException}
* is throwed during concurrency management.
*/
public T execute(T record, Model model, ConcurrencyCallback<T> action) {
try {
// Execute the provided action and return the result
return action.doInConcurrency(record);
} catch (ObjectOptimisticLockingFailureException ex) {
// If some Concurrency Exception appears, log the error as debug level
// and throws a custom exception that contains all the information about
// the view layer.
LOGGER.debug(ex.getLocalizedMessage());
throw new ConcurrencyException(this.manager, record, model, ex);
} catch(Exception e){
throw new ConcurrencyTemplateException(e);
}
}
@Override
@Retryable(maxAttempts = 10, backoff = @Backoff(delay = 100, maxDelay = 500),
include = {ObjectOptimisticLockingFailureException.class, OptimisticLockException.class, DataIntegrityViolationException.class})
@Transactional(REQUIRES_NEW)
public LifecycleEntity saveLifecycle(final ApplicationEntity applicationEntity, final VersionEntity versionEntity,
final LifecycleEntity lifecycleToSave) {
Assert.notNull(applicationEntity, "applicationEntity must not be null");
Assert.notNull(versionEntity, "versionEntity must not be null");
Assert.notNull(lifecycleToSave, "lifecycleToSave must not be null");
ApplicationEntity applicationByName = applicationRepository.findByName(applicationEntity.getName());
VersionEntity versionByName = versionRepository.findByName(versionEntity.getName());
if (applicationByName == null) {
applicationByName = applicationRepository.save(applicationEntity);
}
if (versionByName == null) {
versionByName = versionRepository.save(versionEntity);
}
if (!applicationByName.getVersionEntities().contains(versionByName)) {
applicationByName.getVersionEntities().add(versionByName);
applicationByName = applicationRepository.save(applicationByName);
}
lifecycleToSave.setApplicationEntity(applicationByName);
lifecycleToSave.setVersionEntity(versionByName);
return lifecycleRepository.save(lifecycleToSave);
}