在我以前的文章中,我谈到了对MongoDB批处理程序采用乐观锁定的好处。 如我之前所写,乐观锁异常是可恢复的异常,只要我们获取最新的Entity,我们就会对其进行更新并保存。

因为我们使用的是MongoDB,所以我们不必担心本地或XA事务。 在以后的文章中,我将演示如何使用JPA构建相同的机制。

Spring框架提供了很好的AOP支持,因此可以轻松实现自动重试机制,这就是我的方法。

我们首先定义一个Retry注释:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Retry {Class<? extends Exception>[] on();int times() default 1;
}

我们注释了我们的业务逻辑方法,例如

@Retry(times = 10, on = org.springframework.dao.OptimisticLockingFailureException.class)
public Product updateName(Long id, String name) {Product product = productRepository.findOne(id);product.setName(name);LOGGER.info("Updating product {} name to {}", product, name);return productRepository.save(product);
}

然后,我们只需要AOP方面来拦截业务逻辑调用,并在乐观锁定检测的情况下重试。

@Aspect
public class OptimisticConcurrencyControlAspect {private static final Logger LOGGER = LoggerFactory.getLogger(OptimisticConcurrencyControlAspect.class);@Around("@annotation(vladmihalcea.concurrent.Retry)")public Object retry(ProceedingJoinPoint pjp) throws Throwable {Retry retryAnnotation = getRetryAnnotation(pjp);return (retryAnnotation != null) ? proceed(pjp, retryAnnotation) : proceed(pjp);}private Object proceed(ProceedingJoinPoint pjp) throws Throwable {return pjp.proceed();}private Object proceed(ProceedingJoinPoint pjp, Retry retryAnnotation) throws Throwable {int times = retryAnnotation.times();Class<? extends Throwable>[] retryOn = retryAnnotation.on();Assert.isTrue(times > 0, "@Retry{times} should be greater than 0!");Assert.isTrue(retryOn.length > 0, "@Retry{on} should have at least one Throwable!");LOGGER.info("Proceed with {} retries on {}", times, Arrays.toString(retryOn));return tryProceeding(pjp, times, retryOn);}private Object tryProceeding(ProceedingJoinPoint pjp, int times, Class<? extends Throwable>[] retryOn) throws Throwable {try {return proceed(pjp);} catch (Throwable throwable) {if(isRetryThrowable(throwable, retryOn) && times-- > 0) {LOGGER.info("Optimistic locking detected, {} remaining retries on {}", times, Arrays.toString(retryOn));return tryProceeding(pjp, times, retryOn);}throw throwable;}}private boolean isRetryThrowable(Throwable throwable, Class<? extends Throwable>[] retryOn) {Throwable[] causes = ExceptionUtils.getThrowables(throwable);for(Throwable cause : causes) {for(Class<? extends Throwable> retryThrowable : retryOn) {if(retryThrowable.isAssignableFrom(cause.getClass())) {return true;}}}return false;}private Retry getRetryAnnotation(ProceedingJoinPoint pjp) throws NoSuchMethodException {MethodSignature signature = (MethodSignature) pjp.getSignature();Method method = signature.getMethod();Retry retryAnnotation = AnnotationUtils.findAnnotation(method, Retry.class);if(retryAnnotation != null) {return retryAnnotation;}Class[] argClasses = new Class[pjp.getArgs().length];for (int i = 0; i < pjp.getArgs().length; i++) {argClasses[i] = pjp.getArgs()[i].getClass();}method = pjp.getTarget().getClass().getMethod(pjp.getSignature().getName(), argClasses);return AnnotationUtils.findAnnotation(method, Retry.class);}
}

测试开始了10个竞标以竞争产品的保存,这就是测试日志。

Line 492: INFO  [Thread-9]: v.c.a.OptimisticConcurrencyControlAspect - Optimistic locking detected, 9 remaining retries on [class org.springframework.dao.OptimisticLockingFailureException]Line 495: INFO  [Thread-3]: v.c.a.OptimisticConcurrencyControlAspect - Optimistic locking detected, 9 remaining retries on [class org.springframework.dao.OptimisticLockingFailureException]Line 504: INFO  [Thread-8]: v.c.a.OptimisticConcurrencyControlAspect - Optimistic locking detected, 9 remaining retries on [class org.springframework.dao.OptimisticLockingFailureException]Line 505: INFO  [Thread-11]: v.c.a.OptimisticConcurrencyControlAspect - Optimistic locking detected, 9 remaining retries on [class org.springframework.dao.OptimisticLockingFailureException]Line 507: INFO  [Thread-10]: v.c.a.OptimisticConcurrencyControlAspect - Optimistic locking detected, 9 remaining retries on [class org.springframework.dao.OptimisticLockingFailureException]Line 513: INFO  [Thread-5]: v.c.a.OptimisticConcurrencyControlAspect - Optimistic locking detected, 9 remaining retries on [class org.springframework.dao.OptimisticLockingFailureException]Line 523: INFO  [Thread-4]: v.c.a.OptimisticConcurrencyControlAspect - Optimistic locking detected, 9 remaining retries on [class org.springframework.dao.OptimisticLockingFailureException]Line 529: INFO  [Thread-3]: v.c.a.OptimisticConcurrencyControlAspect - Optimistic locking detected, 8 remaining retries on [class org.springframework.dao.OptimisticLockingFailureException]Line 586: INFO  [Thread-10]: v.c.a.OptimisticConcurrencyControlAspect - Optimistic locking detected, 8 remaining retries on [class org.springframework.dao.OptimisticLockingFailureException]Line 682: INFO  [Thread-5]: v.c.a.OptimisticConcurrencyControlAspect - Optimistic locking detected, 8 remaining retries on [class org.springframework.dao.OptimisticLockingFailureException]Line 683: INFO  [Thread-3]: v.c.a.OptimisticConcurrencyControlAspect - Optimistic locking detected, 7 remaining retries on [class org.springframework.dao.OptimisticLockingFailureException]Line 686: INFO  [Thread-8]: v.c.a.OptimisticConcurrencyControlAspect - Optimistic locking detected, 8 remaining retries on [class org.springframework.dao.OptimisticLockingFailureException]Line 702: INFO  [Thread-3]: v.c.a.OptimisticConcurrencyControlAspect - Optimistic locking detected, 6 remaining retries on [class org.springframework.dao.OptimisticLockingFailureException]Line 752: INFO  [Thread-5]: v.c.a.OptimisticConcurrencyControlAspect - Optimistic locking detected, 7 remaining retries on [class org.springframework.dao.OptimisticLockingFailureException]Line 756: INFO  [Thread-8]: v.c.a.OptimisticConcurrencyControlAspect - Optimistic locking detected, 7 remaining retries on [class org.springframework.dao.OptimisticLockingFailureException]Line 859: INFO  [Thread-5]: v.c.a.OptimisticConcurrencyControlAspect - Optimistic locking detected, 6 remaining retries on [class org.springframework.dao.OptimisticLockingFailureException]
  • 代码可在GitHub上获得 。
参考:来自Vlad Mihalcea博客博客的JCG合作伙伴 Vlad Mihalcea 对MongoDB进行了乐观锁定重试 。

翻译自: https://www.javacodegeeks.com/2013/11/optimistic-locking-retry-with-mongodb.html

使用MongoDB进行乐观锁定重试相关推荐

  1. mongodb启动不能锁定_使用MongoDB进行乐观锁定重试

    mongodb启动不能锁定 在我以前的文章中,我谈到了对MongoDB批处理程序采用乐观锁定的好处. 如我之前所写,乐观锁定异常是可恢复的异常,只要我们获取最新的Entity,我们就会对其进行更新并保 ...

  2. oracle中悲观锁定_如何使用悲观锁定修复乐观锁定竞争条件

    oracle中悲观锁定 回顾 在我以前的文章中 ,我解释了使用显式乐观锁定的好处. 然后我们发现,在很短的时间范围内,并发交易仍可以在我们当前交易被提交之前立即提交产品价格更改. 此问题可以描述如下: ...

  3. hibernate工厂模式_Hibernate锁定模式–乐观锁定模式如何工作

    hibernate工厂模式 显式乐观锁定 在上一篇文章中 ,我介绍了Java持久性锁定的基本概念. 隐式锁定机制可防止丢失更新 ,它适用于我们可以主动修改的实体. 尽管隐式乐观锁定是一种广泛使用的技术 ...

  4. hibernate乐观锁_Hibernate Collection乐观锁定

    hibernate乐观锁 介绍 Hibernate提供了一种乐观的锁定机制 ,即使长时间通话也可以防止更新丢失 . 结合实体存储,跨越多个用户请求(扩展的持久性上下文或分离的实体),Hibernate ...

  5. 如何使用悲观锁定修复乐观锁定竞争条件

    概括 在我以前的文章中 ,我解释了使用显式乐观锁定的好处. 然后我们发现,在很短的时间范围内,并发交易仍可以在我们当前交易被提交之前立即提交产品价格更改. 此问题可以描述如下: 爱丽丝拿产品 然后,她 ...

  6. 休眠锁定模式–乐观锁定模式如何工作

    显式乐观锁定 在上一篇文章中 ,我介绍了Java持久性锁定的基本概念. 隐式锁定机制可防止丢失更新 ,它适用于我们可以主动修改的实体. 虽然隐式乐观锁定是一种广泛使用的技术,但是很少有人了解显式乐观锁 ...

  7. Hibernate Collection乐观锁定

    介绍 Hibernate提供了一种乐观的锁定机制 ,即使长时间通话也可以防止丢失更新 . 结合实体存储,跨越多个用户请求(扩展的持久性上下文或分离的实体),Hibernate可以保证应用程序级的可重复 ...

  8. SQL的「悲观锁定」与「乐观锁定」

          今天在做设计书的时候,遇到了这两个词:「悲观锁定」与「乐观锁定」,于是回了总结一下. 悲观锁定方式: 当我们在对数据库进行更新操作的时候,有时候我们为了防止冲突,使用数据库为我们 提供的, ...

  9. 使用弹簧启动和 JPA 测试乐观锁定处理

    虽然 JPA 中的乐观锁定处理是相对众所周知的,但它通常测试得很差或根本没有测试. 在这篇博文中,我将首先向您展示乐观锁定处理的含义,以及如何在 Spring 引导应用程序和 JPA 中实现它. 之后 ...

最新文章

  1. MyEclipse教程:Web开发——创建Web片段项目
  2. 知识图谱学习笔记-Cypher语句使用
  3. OSPF的LSA类型 ——连载一路由器LSA
  4. SAP Intelligent Robotic Process Automation权限控制
  5. 手机编写python程序_Python实现自动上京东抢手机
  6. 哈夫曼算法(huffman algorithm C)
  7. 微软警告 Windows 10 1703 即将停止支持!
  8. 华为计算机充电指示灯,数码产品:华为p40充电指示灯不亮在哪里设置 有指示灯吗...
  9. 计算机学院毕业生德育总结,毕业生德育答辩总结_相关文章专题_写写帮文库
  10. 【模型库】大卡车货车 集装箱 叉车 三维模型
  11. Mac M1安装pycharm专业版,幼儿教学
  12. 为什么用conda?
  13. 小程序自定义底部菜单栏
  14. 14宽的键槽深度多少_平键和键槽标准尺寸规格表.doc
  15. VS2015一些使用技巧
  16. “逃犯克星”张学友演唱会完成八杀,幕后功臣竟然是它
  17. 微信小程序基于OCR插件实现图文识别(超简单)
  18. 犀牛中斑马纹分析的作用
  19. 如何轻松地的现货白银中预测走势?
  20. html实现手风琴轮播图,jQuery手风琴轮播图

热门文章

  1. mysql error 1045 的解决方法
  2. 数据库编程——intro to JDBC
  3. 防止用户重复提交表单数据,session方式,js方式
  4. java orm框架有哪些_Java Stream ORM现在带有JOIN
  5. spring health_为什么Spring的Health会再次向下,向下,向上,向上,向上和向下?...
  6. dc/os_DC / OS中具有Java和数据库应用程序的服务发现
  7. 不可变集合相比可变集合_简单的基准测试:不可变集合VS持久集合
  8. 什么是序列化? 您需要通过示例解释的有关Java序列化的所有知识
  9. JDK 9、10和11中的安全性增强
  10. API测试和自动化101:基本指南