使用MongoDB进行乐观锁定重试

在我以前的文章中,我谈到了对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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366839.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

cx oracle 配置,cx_Oracle的配置啊。。终于搞出来了

参考。。http://www.blogjava.net/jelver/articles/294583.htmlhttp://shanchao7932297.blog.163.com/blog/static/1363624200710911543428/http://aofengblog.blog.163.com/blog/static/6317021201157111336764/http://www.cnblogs.com/ysisl/archive/2010/12/20/1911870.html…

JavaScript中发布/订阅模式的理解

订阅发布模式的介绍 发布订阅模式&#xff0c;它定义了一种一对多的关系&#xff0c;可以使多个观察者对象对一个主题对象进行监听&#xff0c;当这个主题对象发生改变时&#xff0c;依赖的所有对象都会被通知到。 在生活中我们常常遇到这样一种情况&#xff0c;我们在使用新…

java的list遍历

for(String str : list) {//增强for循环&#xff0c;其内部实质上还是调用了迭代器遍历方式&#xff0c;这种循环方式还有其他限制&#xff0c;不建议使用。System.out.println(str); } for( int i 0 ; i < list.size() ; i) {//普通for循环&#xff0c;内部不锁定&#xf…

Spring Data Solr入门

Spring Data Solr是Spring Data项目的扩展&#xff0c;该项目旨在简化Apache Solr在Spring应用程序中的使用。 请注意&#xff0c;这不是Spring&#xff08;数据&#xff09;或Solr的简介。 我认为您至少对这两种技术都有一些基本的了解。 在下面的文章中&#xff0c;我将展示如…

一个关于fixed抖动的小bug

前言 大家都知道position: fixed用于生成绝对定位的元素&#xff0c;相对于浏览器窗口进行定位。 元素的位置通过 "left", "top", "right" 以及 "bottom" 属性进行规定。 突然发现自己之前写的网页有个小bug&#xff1a;在购买页面的…

BBS论坛(十八)

18.首页轮播图实现 &#xff08;1&#xff09;front/css/front_base.css .main-container{width: 990px;margin: 0 auto;overflow: hidden; } .lg-container{width: 730px;float:left; } .sm-container{width: 250px;float:right; } &#xff08;2&#xff09;front_base.html …

eureka-7-多网卡下的ip选择

目前没有需求,后面需要的话&#xff0c;再补充 只是简单使用的话&#xff0c;只需要指定ip即可 eureka.instance.ip-address:127.0.0.1转载于:https://www.cnblogs.com/wenq001/p/9884591.html

Java DB中的Java用户定义类型(UDT)

Java DB是基于Java编程语言和SQL的关系数据库管理系统。 这是Apache软件基金会的开源Derby项目的Oracle版本。 Java SE 7 SDK中包含Java DB。 用户定义类型&#xff08;UDT&#xff09;是Java类&#xff0c;其实例&#xff08;对象&#xff09;存储在数据库表列中。 UDT定义为…

php 字符串与数字相加,注意!PHP中字符串与数字的比较

在日常开发过程中&#xff0c; 运算符是我们每天都会接触到的。这个运算符中其实埋了非常多的坑&#xff0c;今天我们就来看下字符串和数字用比较需要注意的问题。首先来看看这些代码&#xff1a;echo "1234" " 1234" is . (1234 1234), PHP_EOL;echo …

腾讯Node.js基础设施TSW正式开源

经过六年的迭代与沉淀&#xff0c;腾讯Tencent Server Web (以下简称TSW)这一公司级运维组件于今日正式开源。TSW是面向WEB前端开发者&#xff0c;以提升问题定位效率为初衷&#xff0c;提供云抓包、全息日志和异常发现的Node.js基础设施。TSW每天为百亿次请求提供稳定服务&…

Luogu P1535 【游荡的奶牛】

搜索不知道为什么没有人写bfs觉得挺像是标准个bfs的 状态因为要统计次数&#xff0c;不能简单地跳过一个被经过的点这样的话&#xff0c;状态量会爆炸采用记忆化设dp[i][j][k]表示在第k分钟到达点(i,j)的方案数以地点时间作为状态避免同一状态被反复拓展这样&#xff0c;状态量…

ORM框架greenDao 2 (用于了解旧版本的使用方法,目前最新版本为3.2.2,使用注释的方式来生成)...

摘要&#xff1a; Android中对SQLite数据库使用&#xff0c;是一件非常频繁的事情。现今&#xff0c;也有非常多的SQLite处理的开源框架&#xff0c;其中最著名的greenDao&#xff0c;它以占用资源少&#xff0c;处理效率高等特点&#xff0c;成为优秀的ORM框架之一。那么对于g…

配置MySQL以进行ADF开发

大家好。 今天&#xff0c;我将向您展示如何为Oracle ADF开发配置MySQL数据库。 恕我直言&#xff0c;当您将ADF与其他数据库而不是Oracle DB一起使用时&#xff0c;您将无法使用Oracle ADF的全部功能&#xff0c;有时您会发现自己正在寻找解决方法&#xff0c;以实现某些行为…

linux 强行杀死进程,Linux如何查看进程、杀死进程、启动进程等常用命令

查进程杀进程使用kill命令结束进程&#xff1a;常用&#xff1a;Linux下还提供了一个killall命令&#xff0c;可以直接使用进程的名字而不是进程标识号&#xff0c;例如&#xff1a;进入到进程的执行文件所在的路径下&#xff0c;执行文件 ./文件名附&#xff1a;修改文件日期命…

React Native面试知识点

本文原创首发于公众号&#xff1a;ReactNative开发圈&#xff0c;转载需注明出处。 本文会不定期不断更新&#xff0c;想查看最新版本请移步至https://github.com/forrest23/react-native-interview 1.React Native相对于原生的ios和Android有哪些优势&#xff1f; 1.性能媲美…

KIE-WB / JBPM控制台Ng –配置

大家好&#xff0c;这是我上一篇文章中有关如何使用jBPM Console的后续文章 。 这篇文章的主要思想是描述为了在您自己的公司中使用它&#xff0c;您需要对jBPM Console NG进行一些最常见的配置。 但是在讨论技术细节之前&#xff0c;我们将介绍KIE Workbench&#xff08;KIE-W…

EasyUI常用控件禁用方法

来自&#xff1a;http://blog.csdn.net/jin_guang/article/details/36905387 特此感谢 1.validatebox可以用的用法:前两种适用于单个的validatebox; 第三种应用于整个form里面的输入框; <1>.$("#id").attr("readonly", true); ----- $("#id…

linux内核percpu变量声明,Linux kernel percpu变量解析

Linux 2.6 kernel 中的 percpu 变量是经常用到的东西&#xff0c;因为现在很多计算机都已经支持多处理器了&#xff0c;而且 kernel 默认都会被编译成 SMP 的&#xff0c;相对于原来多个处理器共享数据并进行处理的方式&#xff0c;用 percpu 变量在 SMP、NUMA 等架构下可以提高…

django组件 分页器

1 from django.shortcuts import render,HttpResponse2 3 # Create your views here.4 from app01.models import *5 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger6 7 def index(request):8 9 10 批量导入数据: 11 12 Booklist[] …

自己写一个H5项目CI系统

持续集成&#xff08;Continuous integration&#xff0c;简称CI)系统在软件自动化构建&#xff08;包括编译、发布、自动化测试&#xff09;方面有着重要的作用&#xff0c;在之前&#xff0c;前端项目简单&#xff0c;很多时候发布都只是一些简单的拷贝&#xff0c;而随着web…