新增操作 失败后重试_可重试的操作

新增操作 失败后重试

在我从事的每个项目中,始终需要某些功能:重试操作。 通常,这是关于通过网络的呼叫,该呼叫可能一次失败,但随后会成功。 它可能涉及许多其他内容,主要包括与另一个系统的通信(无论是否通过网络)。 它的功能,你绝对需要在大多数应用中,特别是如果你想他们是高可用性( 如这里指出的 ,例如)。

每次我必须在项目中引入此功能时,我都会检查我们已导入的标准库,没有这样的东西。 因此,我总是最终将我以前的项目中的同一段代码复制粘贴。 我什至不记得我是什么时候第一次介绍它的,但是从那以后我就在“旅行”。 所以这里是:

/*** Class that provides retrying functionality. Example:* <p></p>* <code>* Callable<String> callable = new Callable<String>() {..};* String result = RetryableOperation.create(callable).retry(5, IOException.class);* </code>** @param <T> the return type of the operation*/
public class RetryableOperation<T> {private Callable<T> callable;private Runnable runnable;private boolean exponentialBackoff;private int backoffInterval = 500;/*** Create a retryable operation based on a Callable instance. The return* type of retry(..) is the type parameter of the Callable instance.** @param callable* @return*      a new instance of RetryableOperation*/public static <T> RetryableOperation<T> create(Callable<T> callable) {return new RetryableOperation<T>().withCallable(callable);}/*** Creates a retryable operation based on a Runnable instance. In this case* the retry(..) method always returns null.** @param runnable* @return*      a new instance of RetryableOperation*/public static RetryableOperation<?> create(Runnable runnable) {return new RetryableOperation<Object>().withRunnable(runnable);}/*** Retries the operation. Retrying happens regardless of the exception thrown.** @param retries*      number of retries before the exception is thrown to the caller* @param exceptions*      the operation will be retried only if the exception that occurs is one of the*      exceptions passed in this array* @return*      the result of the operation (null if Runnable is used instead of Callable)* @throws Exception*      the exception that occurred on the last attempt*/public T retry(int retries, Class<? extends Exception>... exceptions) throws Exception {if (callable == null && runnable == null) {throw new IllegalStateException("Either runnable or callable must be set");}Set<Class<? extends Exception>> retryFor = new HashSet<Class<? extends Exception>>();retryFor.addAll(Arrays.asList(exceptions));for (int i = 0; i < retries; i++) {try {if (exponentialBackoff && i > 0) {int sleepTime = (int) ((Math.pow(2, i) - 1) / 2) * backoffInterval;Thread.sleep(sleepTime);}if (callable != null) {return callable.call();} else if (runnable != null) {runnable.run();return null;}} catch (Exception e) {if (retryFor.isEmpty() || retryFor.contains(e.getClass())) {if (i == retries - 1) {throw e;}} else {// if the exception is not the expected one, throw it immediatelythrow e;}}}// can't be reached - in case of failure on the last iteration the exception is rethrownreturn null;}private RetryableOperation<T> withCallable(Callable<T> callable) {this.callable = callable;return this;}private RetryableOperation<T> withRunnable(Runnable runnable) {this.runnable = runnable;return this;}public RetryableOperation<T> withExponentialBackoff() {this.exponentialBackoff = true;return this;}
}
1

这很简单,但是效果很好。 您可以重试每个失败,也可以重试特定的异常(您不想重试NullPointerException,但是必须配置适当的超时,然后重试网络故障):

Result result = op.retry(3);...Result result = op.retry(3, IOException.class);

我什至曾建议番石榴将其包含在内,然后再看其他类似的提案,但据我所知,番石榴或apache commons中都没有这种功能。 而且我不会创建一个新的github项目,因为那将需要在maven Central中管理一个条目,而对于单个实用程序类来说,这是一项很大的工作。

当然,还有其他解决方法,它们具有更大的API和占用空间- 重试番石榴扩展和最近提取为单独的项目spring-retry 。 它们值得检查,并且具有要导入的Maven依赖项。

无论选择什么选项,请检查它是否支持匿名功能(自Java 8起)。 它可能会自动执行,但仍会检查。

关键是要通过一个非常简单的API来提供此功能,以便您可以避免用户可避免的故障-必须重试几次对外部系统的调用。

翻译自: https://www.javacodegeeks.com/2015/10/retryable-operations.html

新增操作 失败后重试

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

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

相关文章

mysql uroot e_批量 kill mysql 连接

事故重现,并且加入一些后期想到的想法作为演义. 今天 mysql 服务器负载过高, 主库上主要是写的操作,首先看有没有锁表的,发现没有.mysql -uroot -e "show processlist"|grep -i locked|wc -l再看delete,update,insert操作的数量.mysql -uroot -e "show process…

设计模式适配器模式_适配器设计模式示例

设计模式适配器模式本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &…

mysql mgr bug_Mysql MGR架构误操作引发的问题处理

【背景介绍】故障方描述&#xff1a;一次用户刷权限的时候不小心把数据库用户表记录删掉了&#xff0c;执行之后发现不对后重建用户&#xff0c;杀掉进程后重新MGR启动报错。【报错信息】2018-06-13T12:47:41.405593Z 32 [Note] Plugin group_replication reported: Group comm…

css外墙法_外墙设计模式示例

css外墙法本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &#xff0…

向 mysql导入数据 源码_MySQL 导入数据

MySQL 导入数据MySQL中可以使用两种简单的方式来导入MySQL导出的数据。使用 LOAD DATA 导入数据MySQL 中提供了LOAD DATA INFILE语句来插入数据。以下实例中将从当前目录中读取文件 dump.txt &#xff0c;将该文件中的数据插入到当前数据库的 mytbl 表中。mysql> LOAD DATA …

设计模式示例_桥梁设计模式示例

设计模式示例本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &#x…

数值分析 使用c语言 源码_分析源码,学会正确使用 Java 线程池

在日常的开发工作当中&#xff0c;线程池往往承载着一个应用中最重要的业务逻辑&#xff0c;因此我们有必要更多地去关注线程池的执行情况&#xff0c;包括异常的处理和分析等。本文主要聚焦在如何正确使用线程池上&#xff0c;以及提供一些实用的建议。文中会稍微涉及到一些线…

设计模式示例_状态设计模式示例

设计模式示例本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &#x…

cam350 不能打开光绘文件_如何在CAM350中导入Allegro光绘

内容简介&#xff1a;本人之前遇到过 CAM350 导入 Allegro 格式光绘后钻孔偏移、异型孔不显示的问题&#xff0c;捣鼓过之后找到一个方法&#xff0c;在 Allegro 群友的建议下制作该文档进行适当的说明。1. 导入 Gerber 文件鉴于手工导入 Gerber 文件需要逐层设置&#xff0c;过…

mockito验证参数_Mockito验证

mockito验证参数本文是我们名为“ 用Mockito测试 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入了解Mockito的魔力。 您将了解有关“模拟”&#xff0c;“间谍”和“部分模拟”的信息&#xff0c;以及它们相应的存根行为。 您还将看到使用测试双打和对象匹配器进行验…

d3js mysql_D3.js入门指南

近期略有点诸事不顺&#xff0c;趁略有闲余之时&#xff0c;玩起D3.js。之前实际项目中主要是用各种chart如hightchart、echarts等&#xff0c;这些图形库玩起来貌都是完美的&#xff0c;一切皆可配置&#xff0c;但几年前接触了D3之后&#xff0c;觉得前面那chart类库局限的地…

docker 镜像选择_为什么选择Docker?

docker 镜像选择容器并不是什么新鲜事物&#xff0c;但是实现它们总是比需要的要复杂一些。 Docker在简化容器方面取得了长足的进步&#xff0c;并从此引爆了整个世界。 让我们看看为什么。 为什么Docker成为家喻户晓的名字 Docker不是很老。 2014年5月&#xff0c;当我写了一…

layui templet格式化_layui使用templet格式化表格数据的方法

增加js/*---------------------格式化时间开始--------------------------*///对Date的扩展&#xff0c;将 Date 转化为指定格式的String//月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符&#xff0c;//年(y)可以用 1-4 个占位符&#xff0c;毫秒(S)只能用…

设计模式示例_代理设计模式示例

设计模式示例本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &#x…

mysql insert 字符集_有关 MySQL 字符集的注意事项-爱可生

本文关键字&#xff1a;字符集、建库建表一、数据库和字符集1. 建库时指定创建数据库时&#xff0c;显式指定字符集和排序规则&#xff0c;同时&#xff0c;当切换到当前数据库后&#xff0c;参数 character_set_database&#xff0c;collation_database 分别被覆盖为当前显式指…

c#发送讯息_企业讯息

c#发送讯息本文是我们名为“ EAI的Spring集成 ”的学院课程的一部分。 在本课程中&#xff0c;向您介绍了企业应用程序集成模式以及Spring Integration如何解决它们。 接下来&#xff0c;您将深入研究Spring Integration的基础知识&#xff0c;例如通道&#xff0c;转换器和适…

mysql触发器中case语句_一个很好的触发器例子(case when)

CREATE OR REPLACE TRIGGER TR_CGD1BEFORE UPDATE OR INSERT OR DELETE ON BB_MJ_CGD1_TBFOR EACH ROWDECLAREV_COUNT NUMBER;BEGINCASEWHEN UPDATING OR INSERTING THENIF :NEW.DJZT 结束 THEN:NEW.DJZT : 结束;ELSESELECT COUNT(*)INTO V_COUNTFROM BB_MJ_KCRKD2_TB RKD2WHE…

java cr_WildFly 10 CR 2发布– Java EE 7,Java 8,Hibernate 5,JavaScript支持热重载

java cr昨天&#xff0c;WildFly团队发布了最新版本的WildFly 10 。 CR2很可能是预计于十月份发布最终版本之前的最后一个版本。 即使主要支持的Java EE规范是7&#xff0c;WildFly 8和WildFly 9也提供了许多新功能&#xff0c;而WildFly 9和WildFly 9现在制作了三个服务器版本…

python位置参数ppt_如何在Python中使用一个或多个相同的位置参数?

介绍..如果我们正在编写一个对两个数字执行算术运算的程序&#xff0c;则可以将它们定义为两个位置参数。但是由于它们是相同种类的/ python数据类型的参数&#xff0c;因此使用nargs选项告诉argparse您确实需要两种相同的类型可能更有意义。怎么做..1.让我们编写一个程序来减去…

java设计模式教程_Java设计模式教程

java设计模式教程课程大纲 架构和计算机科学中的设计模式是记录特定专业领域中设计问题的解决方案的正式方法。 这个想法是由建筑师Christopher Alexander在建筑领域引入的&#xff0c;并已被修改为包括计算机科学在内的其他各个学科。 设计模式是针对软件设计中给定上下文中常…