Spring使用@Async实现异步

使用场景

在实际项目中,一个接口如果需要处理很多数据,如果是同步执行,通过网络请求接口可能会出现请求超时。这时候就需要使用异步执行处理了。

使用经验

  • 代码

    • 异步服务类

      @Service // Spring容器托管
      @EnableAsync // *开启异步,有这个注解的类Spring才会进行异步处理
      public class AsyncBizImpl implements AsyncBiz{
      
        @Autowired
        private AsyncDao asynDao;
      
        @Async // *这个是需要异步执行的函数
        @Override
        public void async() {
              transactionMethod();
        }
      
        @Override
        public void setStateBeforeAsync() {
              asynDao.setState();
        }
          
        @Transactional // 将需要加事务的封装到另一个函数
        public void transactionMethod() {
              // 如果需要回滚外层调用者的数据库操作,才需要捕捉异常
            try {
                asynDao.dbOperation(); // 数据库操作
            } catch (Exception e) {  // 捕捉异常进行外层调用者手动回滚
                asynDao.releaseState(); // 调用者数据库操作的反向操作 
                throw new RuntimeException("错误信息"); // 抛异常给@Transactional回滚数据库操作
            }
        }
      }
      
    • 外层调用类

      @Service // Spring容器托管
      public class AsyncServiceImpl implements AsyncService{
      
        @Autowired
        private AsyncBiz asyncBiz;
      
        @Override
        public boolean async() {
            asyncBiz.setStateBeforeAsync(); // 设置标识
            asyncBiz.async(); // 异步方法
            return true;
        }
      
      }
      
  • 总结

    • 需要被Spring托管

      • @Service等
    • 类需要开启异步功能

      • @EnableAsync
    • 执行异步的方法

      • 返回值
        • void
        • Future
      • 非静态类
      • 添加注解@Async
      • 需要事务的语句封装成方法
        • 对应方法添加@Transactional
      • 如果需要回滚外层的数据库操作
        • 需要捕捉异常,执行反向操作的函数
        • 捕捉异常后要重新抛出新的异常,否则与@Transactional冲突
posted @ 2020-05-04 21:34  Sicko  阅读(587)  评论(0)    收藏  举报