精华内容
下载资源
问答
  • 定义重试切面方法,是为了发生乐观锁异常时在一个全新的事务里提交上一次的操作,直到达到重试上限;因此切面实现 org.springframework.core.Ordered 接口,这样我们就可以把切面的优先级设定为高于事务通知 。 ...

    乐观锁:

    model实体类加version字段

     

    
        @JsonProperty("_version")
        @Column(name = "version", nullable = false)
        @Version
        private Long version = 0L;
    

     

     

    问题场景

     先在库里查询出该实体,转化为持久态,在这时库里的该数据被修改了,并且version发生变更,此时持久态实体进行save操作,会触发乐观锁异常。

     

    1:解决方案

         定义Aspectj拦截器,指定方法发生乐观锁异常时,进行重试。

     

    2:show coding.

     

    (1) 因为不是所有方法发生乐观锁异常都是需要重试机制的,所以需要先定义切面接口定义IsTryAgain

    /** 
     * 自定义尝试切面接口 
     */  
    @Retention(RetentionPolicy.RUNTIME)  
    public @interface IsTryAgain {  
        // marker annotation  
    }  

     (2)Service接口方法加上切面接口定义

    /** 
     * 并发乐观锁需要重试的方法 
     */  
    @IsTryAgain  
    boolean TryAgainMethod() throws Exception;  

    (3)定义Aspectj切面拦截器

     

    定义重试切面方法,是为了发生乐观锁异常时在一个全新的事务里提交上一次的操作,直到达到重试上限;因此切面实现 org.springframework.core.Ordered 接口,这样我们就可以把切面的优先级设定为高于事务通知 。

    @Aspect  
    public class SystemArchitecture {  
          
        @Pointcut("execution(* myapp..service..*(..))")  
        public void businessService() {  
        }  
          
    }  
    @Aspect   
    class ConcurrentOperationExecutor implements Ordered {  
         
       private static final int DEFAULT_MAX_RETRIES = 2;  
      
       private int maxRetries = DEFAULT_MAX_RETRIES;  
       private int order = 1;  
      
       public void setMaxRetries(int maxRetries) {  
          this.maxRetries = maxRetries;  
       }  
         
       public int getOrder() {  
          return this.order;  
       }  
         
       @Around("myapp.SystemArchitecture.businessService()")  
       public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable {   
          int numAttempts = 0;  
          PessimisticLockingFailureException lockFailureException;  
          do {  
             numAttempts++;  
             try {   
                return pjp.proceed();  
             }  
             catch(PessimisticLockingFailureException ex) {  
                lockFailureException = ex;  
             }  
          }while(numAttempts <= this.maxRetries);  
      
            
          throw lockFailureException;  
       }  
      
    }  

     3:更多

    AOP知识,Spring AOP和Aspectj的知识。

    展开全文
  • 并发锁事务重试机制(JPA高并发下的乐观锁异常)      我的博文中,有一篇短文Java结合Junit做并发测试用例,是介绍JPA在高并发下,多个Service方法更新 同一个记录;在异常信息中有...

    接入ping++支付,账户余额的数据安全问题,使用jpa乐观锁+AOP重试机制

    乐观锁:
    <span style="white-space:pre">	</span>model实体类加version字段
    <span style="white-space:pre">	</span>private Integer version=0;   //jpa乐观锁
    	
    	@Version
    	@Column(name = "version")
    	public Integer getVersion() {
    		return version;
    	}
    	public void setVersion(Integer version) {
    		this.version = version;
    	}	
    
    
    ---修改实体时,
    <span style="white-space:pre">		</span>tradeBAccount.setVersion(tradeBAccount.getVersion()+1);//乐观锁
    <span style="white-space:pre">		</span>tradeBAccountDao.save(tradeBAccount);
    







    参考:

    并发锁事务重试机制(JPA高并发下的乐观锁异常)

     

     

            我的博文中,有一篇短文Java结合Junit做并发测试用例,是介绍JPA在高并发下,多个Service方法更新

    同一个记录;在异常信息中有StaleObjectStateException和ObjectOptimisticLockingFailureException异常信

    息。有些业务这种靠JPA维护的版本信息是可行的,如果两个不同用户同事(高并发)购买一件马丁靴鞋子,最后会更新该马丁靴在库数量,如果没有重试机制,肯定只有一个用户购买失败;可能这没有什么,用户再次提交购买就ok了;可是作为事逼可能成就人生的工程师,你一定不能容忍,于是有了重试机制。

     

    1:解决方案

         定义Aspectj拦截器,指定方法发生乐观锁异常时,进行重试。

     

    2:show coding.

     

    (1) 因为不是所有方法发生乐观锁异常都是需要重试机制的,所以需要先定义切面接口定义IsTryAgain

    Java代码   收藏代码
    1. /** 
    2.  * 自定义尝试切面接口 
    3.  */  
    4. @Retention(RetentionPolicy.RUNTIME)  
    5. public @interface IsTryAgain {  
    6.     // marker annotation  
    7. }  

     (2)Service接口方法加上切面接口定义

     

    Java代码   收藏代码
    1. /** 
    2.  * 并发乐观锁需要重试的方法 
    3.  */  
    4. @IsTryAgain  
    5. boolean TryAgainMethod() throws Exception;  

     

    (3)定义Aspectj切面拦截器

     

    定义重试切面方法,是为了发生乐观锁异常时在一个全新的事务里提交上一次的操作,直到达到重试上限;因此切面实现 org.springframework.core.Ordered 接口,这样我们就可以把切面的优先级设定为高于事务通知 。

     

    Java代码   收藏代码
    1. @Aspect  
    2. public class SystemArchitecture {  
    3.       
    4.     @Pointcut("execution(* myapp..service..*(..))")  
    5.     public void businessService() {  
    6.     }  
    7.       
    8. }  
     

     

     

     

    Java代码   收藏代码
    1. @Aspect   
    2. class ConcurrentOperationExecutor implements Ordered {  
    3.      
    4.    private static final int DEFAULT_MAX_RETRIES = 2;  
    5.   
    6.    private int maxRetries = DEFAULT_MAX_RETRIES;  
    7.    private int order = 1;  
    8.   
    9.    public void setMaxRetries(int maxRetries) {  
    10.       this.maxRetries = maxRetries;  
    11.    }  
    12.      
    13.    public int getOrder() {  
    14.       return this.order;  
    15.    }  
    16.      
    17.    @Around("myapp.SystemArchitecture.businessService()")  
    18.    public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable {   
    19.       int numAttempts = 0;  
    20.       PessimisticLockingFailureException lockFailureException;  
    21.       do {  
    22.          numAttempts++;  
    23.          try {   
    24.             return pjp.proceed();  
    25.          }  
    26.          catch(PessimisticLockingFailureException ex) {  
    27.             lockFailureException = ex;  
    28.          }  
    29.       }while(numAttempts <= this.maxRetries);  
    30.   
    31.         
    32.       throw lockFailureException;  
    33.    }  
    34.   
    35. }  
     

     3:更多

    AOP知识,Spring AOP和Aspectj的知识。

    展开全文
  • 定义重试切面方法,是为了发生乐观锁异常时在一个全新的事务里提交上一次的操作,直到达到重试上限;因此切面实现 org.springframework.core.Ordered 接口,这样我们就可以把切面的优先级设定为高于事务通知 。 ...

     

            我的博文中,有一篇短文Java结合Junit做并发测试用例,是介绍JPA在高并发下,多个Service方法更新

    同一个记录;在异常信息中有StaleObjectStateException和ObjectOptimisticLockingFailureException异常信

    息。有些业务这种靠JPA维护的版本信息是可行的,如果两个不同用户同事(高并发)购买一件马丁靴鞋子,最后会更新该马丁靴在库数量,如果没有重试机制,肯定只有一个用户购买失败;可能这没有什么,用户再次提交购买就ok了;可是作为事逼可能成就人生的工程师,你一定不能容忍,于是有了重试机制。

     

    1:解决方案

         定义Aspectj拦截器,指定方法发生乐观锁异常时,进行重试。

     

    2:show coding.

     

    (1) 因为不是所有方法发生乐观锁异常都是需要重试机制的,所以需要先定义切面接口定义IsTryAgain

    /**
     * 自定义尝试切面接口
     */
    @Retention(RetentionPolicy.RUNTIME)
    public @interface IsTryAgain {
        // marker annotation
    }

     (2)Service接口方法加上切面接口定义

     

    	
    	/**
    	 * 并发乐观锁需要重试的方法
    	 */
    	@IsTryAgain
    	boolean TryAgainMethod() throws Exception;

     

    (3)定义Aspectj切面拦截器

     

    定义重试切面方法,是为了发生乐观锁异常时在一个全新的事务里提交上一次的操作,直到达到重试上限;因此切面实现 org.springframework.core.Ordered 接口,这样我们就可以把切面的优先级设定为高于事务通知 。

     

    @Aspect
    public class SystemArchitecture {
    	
    	@Pointcut("execution(* myapp..service..*(..))")
    	public void businessService() {
    	}
    	
    }
     

     

     

     

    @Aspect 
    class ConcurrentOperationExecutor implements Ordered {
       
       private static final int DEFAULT_MAX_RETRIES = 2;
    
       private int maxRetries = DEFAULT_MAX_RETRIES;
       private int order = 1;
    
       public void setMaxRetries(int maxRetries) {
          this.maxRetries = maxRetries;
       }
       
       public int getOrder() {
          return this.order;
       }
       
       @Around("myapp.SystemArchitecture.businessService()")
       public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable { 
          int numAttempts = 0;
          PessimisticLockingFailureException lockFailureException;
          do {
             numAttempts++;
             try { 
                return pjp.proceed();
             }
             catch(PessimisticLockingFailureException ex) {
                lockFailureException = ex;
             }
          }while(numAttempts <= this.maxRetries);
    
          
          throw lockFailureException;
       }
    
    }
     

     3:更多

    AOP知识,Spring AOP和Aspectj的知识。

     

     

     

     

     

     

    展开全文
  • Spring Retry重试机制

    千次阅读 2018-05-09 16:34:34
    在调用第三方接口或者使用mq时,会出现网络抖动,连接超时等网络异常,所以需要重试。为了使处理更加健壮并且不太容易出现故障,后续的尝试操作,有时候会帮助失败的操作最后执行成功。例如,由于网络故障或数据库...

    在调用第三方接口或者使用mq时,会出现网络抖动,连接超时等网络异常,所以需要重试。为了使处理更加健壮并且不太容易出现故障,后续的尝试操作,有时候会帮助失败的操作最后执行成功。例如,由于网络故障或数据库更新中的DeadLockLoserException导致Web服务或RMI服务的远程调用可能会在短暂等待后自行解决。 为了自动执行这些操作的重试,Spring Batch具有RetryOperations策略。不过该重试功能从Spring Batch 2.2.0版本中独立出来,变成了Spring Retry模块。

    引入依赖

        <dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>

    需要引入Spring-retry和aspectjweaver的依赖。

    入口类

    
    @SpringBootApplication
    @EnableRetry
    public class SpringbootRetryApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringbootRetryApplication.class, args);
        }
    }

    入口类上开启retry的拦截,使用@EnableRetry注解。

    Service

    @Service
    public class PayService {
    
        private Logger logger = LoggerFactory.getLogger(getClass());
    
        private final int totalNum = 100000;
    
        @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000L, multiplier = 1.5))
        public int minGoodsnum(int num) throws Exception {
            logger.info("减库存开始" + LocalTime.now());
            try {
                int i = 1 / 0;
            } catch (Exception e) {
                logger.error("illegal");
            }
            if (num <= 0) {
                throw new IllegalArgumentException("数量不对");
            }
            logger.info("减库存执行结束" + LocalTime.now());
            return totalNum - num;
        }
    }

    @Retryable的参数说明:

    • value:抛出指定异常才会重试
    • include:和value一样,默认为空,当exclude也为空时,默认所以异常
    • exclude:指定不处理的异常
    • maxAttempts:最大重试次数,默认3次
    • backoff:重试等待策略,默认使用@Backoff@Backoff的value默认为1000L,我们设置为2000L;multiplier(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。

    测试类

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class SpringbootRetryApplicationTests {
        @Autowired
        private PayService payService;
    
        @Test
        public void payTest() throws Exception {
            int store = payService.minGoodsnum(-1);
            System.out.println("库存为:" + store);
        }
    
    }

    运行的控制台结果如下:

    可以看到,三次之后抛出了IllegalArgumentException异常。

    当重试耗尽时,RetryOperations可以将控制传递给另一个回调,即RecoveryCallback。Spring-Retry还提供了@Recover注解,用于@Retryable重试失败后处理方法,此方法里的异常一定要是@Retryable方法里抛出的异常,否则不会调用这个方法。

    @Recover
    public int recover(Exception e) {
        logger.warn("减库存失败!!!" + LocalTime.now());
        return totalNum;
    }

    在Service中,加上如上的方法之后,进行测试。

    可以看到当三次重试执行完之后,会调用Recovery方法,也不会再次抛出异常。

    总结

    本文主要讲了在Spring Boot项目中的Spring-Retry简单应用,主要是基于注解配置一些重试的策略,使用比较简单。主要的适用场景为在调用第三方接口或者使用mq时。由于会出现网络抖动,连接超时等网络异常,这时就需要重试。

    本文的代码: https://github.com/keets2012/Spring-Cloud_Samples/tree/master/springboot-retry

    订阅最新文章,欢迎关注我的公众号

    微信公众号

    参考

    1. springboot 整合retry(重试机制)
    展开全文
  • spring的@Retryable重试机制

    千次阅读 2019-10-19 10:11:56
    比如说在微服务中,服务之间的调用有时候会因为网络波动导致调用失败,这时候代码中进行失败重试就ok了,当然这种重试机制通常会和异步结合使用,否则因为重试导致响应时间变长,这肯定是不行的。至于异步,无论是...
  • 楔子:翻了帖子两三天,硬是没有找到哪个帖子能证明生产端的消息重试是确实重试了的。大多要么是对概念、源码说明了一下,或者把实现示例贴贴,但基本并没有有效测试证明。想了想,还是自己来捋一捋这 RocketMQ 的...
  • Spring data mongodb事务(注解事务

    万次阅读 热门讨论 2018-12-07 17:16:24
    Spring Boot与mongodb 事务(注解事务) 1.准备工作 1.准备好docker 2.Spring boot 版本为2.1.1.RELEASE及以上 2.安装环境 首先以主从模式安装mongodb 4.0.0以上的数据库实例,使用以下docker命令安装: docker ...
  • 重试有关死锁和事务序列化错误的数据库事务。 支持MySQL,PostgreSQL和SQLite。 例子 通过拯救ActiveRecord :: TransactionIsolationConflict并重试事务,gem自动工作。 安装 将此添加到您的Gemfile中: gem '...
  • 对于开发过网络应用程序的程序员来说,重试并不陌生,由于网络的拥堵和波动,此刻不能访问服务的请求,也许过一小段时间就可以正常访问了。随着重试逻辑的不断变化,上面代码会越来越复杂。而且重试逻辑,其实是各个...
  • } /** * - 在尝试次数内, * 如果抛出的是exclude里面的异常(或其子类异常),那么不再继续重试,直接抛出异常 * 如果抛出的是include里面的异常(或其子类异常),那么仍然会继续重试 */ @Retryable(include = {...
  • RabbitMQ 重试机制和消息幂等性

    千次阅读 2019-05-10 17:40:33
    消费者在消费mq中的消息时,mq已把消息发送给消费者,消费者在给mq返回ack时网络中断,故mq未收到确认信息,该条消息会重新发给其他的消费者,或者在网络连后再次发送给该消费者,但实际上该消费者已成功消费了该...
  • spring-retry重试与熔断详解

    千次阅读 2018-05-05 21:35:48
    本文是《亿级流量》第6章 超时与重试机制补充内容。...spring-retry项目实现了重试和熔断功能,目前已用于SpringBatch、Spring ...RetryOperations定义了重试的API,RetryTemplate提供了模板实现,线程安全的
  • 自动使用事务(transaction) laravel想要在一个数据库事务中运行一连串操作,可以使用DB门面的transaction方法,如果事务闭包中抛出异常,事务将会自动回滚。如果闭包执行成功,事务将会自动提交。使用transaction...
  • RocketMq重试及消息不丢失机制

    千次阅读 2019-05-27 15:57:49
    1、消息重试机制 由于MQ经常处于复杂的分布式系统中,考虑网络波动、服务宕机、程序异常因素,很有可能出现消息发送或者消费失败的问题。因此,消息的重试就是所有MQ中间件必须考虑到的一个关键点。如果没有消息重试...
  • 重试框架Spring retry实践

    万次阅读 2017-09-03 17:16:19
    对于重试室友场景限制的,不是什么场景都适合重试,比如参数校验不合法、写操作等(要考虑写是否幂等)都不适合重试。远程调用超时、网络突然中断可以重试。在微服务治理框架中,通常都有自己的重试与超时配置,比如...
  • 超时与重试机制

    千次阅读 2019-03-15 17:21:16
    网上发现这篇好文章,这里记录学习。 介绍 在实际开发过程中,笔者见过...而有些中间件或者框架在超时后会进行重试(如设置超时重试两次),读服务天然适合重试,但写服务大多不能重试(如写订单,如果写服务是幂等...
  • TIDB事务测试

    千次阅读 2018-03-29 20:13:30
    但是根据实际业务场景:假设存在这种同一用户并发的情况,tidb的事务重试机制可能会产生一些错误数据 待解决问题:综合以上比如在并发情况下账户提现的测试,该如何规避以上错误数据问题。 队列? 关闭tidb重试? ...
  • 分布式系统超时重试

    千次阅读 2018-07-16 09:53:07
    重试的分类 Nginx代理层超时 客户端超时设置 DNS解析超时设置 代理超时设置 网络连接/读/写超时设置 失败重试机制设置 upstream存活超时设置 ngx_lua超时设置 Web容器超时 在实际开发当中,很多故障的产生...
  • Java知识体系最强总结(2021版)

    万次阅读 多人点赞 2019-12-18 10:09:56
    存储过程与函数 视图 MySQL优化 事务 数据备份与还原 Redis Java虚拟机 深入理解Java虚拟机 架构设计 设计模式 创建型模式 结构型模式 行为型模式 J2EE模式 实践应用 应用框架 Spring 《Spring实战》读书笔记 Spring...
  • 分布式事务了解吗?你们是如何解决分布式事务问题的? 面试官心理分析 只要聊到你做了分布式系统,必问分布式事务,你对分布式事务一无所知的话,确实会很坑,你起码得知道有哪些方案,一般怎么来做,每个方案的优...
  • Rocketmq提供了消息重试机制,这是一些其他消息队列没有的功能。我们可以依靠这个优秀的机制,而不用在开发中增加更多的业务代码去实现 消息重试 Consumer 消费消息失败后,要提供一种重试机制,令消息再消费一次...
  • RocketMQ重试策略及与Springboot整合

    千次阅读 2019-10-11 17:28:52
    在消息的发送和消费过程中,都有可能出现错误,如网络异常等,出现了错误就需要进行错误重试,这种消息的重试需要分2种,分别是producer端重试和consumer端重试。 1.1 producer端重试 生产者端的消息失败,也就是...
  • 本文是《亿级流量网站架构核心技术——跟开涛学搭建高可用高并发系统》第6章 超时与重试机制补充内容。  spring-retry项目实现了重试和熔断功能,目前已用于SpringBatch、Spring Integration等项目。    ...
  • 答案:使用消息重试机制。(springboot默认有消息重试机制) 消费者获取到消息后,调用第三方接口,但接口暂时无法访问,是否需要重试?(需要重试机制) 消费者获取到消息后,抛出数据转换异常,是否需要重试?(不需要...
  • Java面试题大全(2020版)

    万次阅读 多人点赞 2019-11-26 11:59:06
    发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全,希望对大家有帮助哈~ 本套Java面试题大全,全的不能再全,哈哈~ 一、Java 基础 1. JDK 和 JRE 有什么区别?...
  • SpringBoot整合RocketMQ、发布订阅、顺序消息、事物消息、消息重试和死信队列 一、RocketMQ RocketMQ是阿里巴巴旗下一款开源的MQ框架,经历过双十一考研、Java编程语言实现,有非常好完整生态系统 Rocketmq相比于...
  • galaxyLight:欢迎大家完善本系统,结合当前事务处理的本质,我开发了太极分布式事务处理框架MOONWATER,采用可靠消息服务和重试,补偿处理机制,使用事件驱动,最终一致的事务模型,替代地部署数据库的事务处理能力...
  • retry重试常见场景及实现

    千次阅读 2018-10-20 16:43:00
    retry重试常见场景及实现  当我们的代码是有访问网络相关的操作时,比如http请求或者访问远程数据库,经常可能会发生一些错误,有些错误可能重新去发送请求就会成功,本文分析常见可能需要重试的场景,并最后...
  • 消息重试 Rocketmq提供了消息重试机制,这是一些其他消息队列没有的功能。我们可以依靠这个优秀的机制,而不用在开发中增加更多的业务代码去实现 Consumer 消费消息失败后,要提供一种重试机制,令消息再消费一次...
  • 利用Spring-Retry定制化你的RPC重试

    千次阅读 2017-12-25 15:00:02
    failfast,即快速失败像上层抛出远程调用异常failover,即 A->B失败,选择集群其他机器A->Bn(1…N) failsafe, 失败吞异常failback, 过一会再重试,比如网络抖动,等一小会在重试。 其中failback则是本文所要讨论的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 117,681
精华内容 47,072
关键字:

事务重试