VVL1295

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Spring 整合 Hibernate 执行异步任务

  本文介绍 Spring 整合 Hibernate 后,如何执行需要进行数据库操作的异步任务;

  1,处理 session 的开启

    其实很简单,只要对执行异步任务的方法织入增强处理即可,而做法就跟普通的 Spring 事务管理的做法一样。跟 Spring 事务管理有什么关系?因为 Spring 事务会好好的管理 session,那就是以下代码即可:

    @Async
    @Transactional(isolation = Isolation.DEFAULT, rollbackFor = Throwable.class, timeout = 300, propagation = Propagation.REQUIRED)
    public void asyncXx(xx) throws Exception {
      // 省略代码
        }
    }

    每个方法都加上 @Transactional 注解比较麻烦,打算在配置文件里面如下粗粒度地控制,但是会报错,配置文件的相关部分如下:

    <aop:config>
        <aop:pointcut expression="execution(* com.gpl.web.controller.*.*(..)) or @annotation(org.springframework.scheduling.annotation.Async)" id="myPointcut"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"/>
    </aop:config>

    错误如下:

org.aspectj.apache.bcel.classfile.ClassFormatException: File: 'org.hibernate.internal.SessionFactoryImpl': Invalid byte tag in constant pool: 18

    官方文档里面也没有“XML 配置文件里面有 @annotation 注解”的配置方式,大概是不支持的;

    换成以下这种配置即会成功(就需要使用 @Transactional 注解了):

    <aop:config>
        <aop:pointcut expression="execution(* com.gpl.web.controller.*.*(..)) or execution(* com.gpl.web.service.impls.*.async*(..))" id="myPointcut"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"/>
    </aop:config>

    这样亦可:

    <aop:config>
        <aop:pointcut expression="execution(* com.gpl.web.controller.*.*(..)) or execution(* com.gpl.web.service.interfaces.*.async*(..))" id="myPointcut"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"/>
    </aop:config>

    可看这篇文章知道 Spring 是如何管理 session 的:http://www.cnblogs.com/VVL1295/p/6280064.html。

  2,处理事务

    同上;

  3,异常处理

    通常异步方法都放在 service 层,抛出的异常就不能用 ExceptionHandler 进行处理了,比较好的方法就是写一个 @Aspect 类织入增强处理(例如用 @AfterThrowing 的方法记录日志),当然,也可以显式手动 try-catch,不过要注意把异常抛出,不然可能会导致事务不能回滚;

  没错,就是这么简单。

  以上。

 

posted on 2017-01-13 11:22  bobo2018  阅读(580)  评论(0)    收藏  举报