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,不过要注意把异常抛出,不然可能会导致事务不能回滚;
没错,就是这么简单。
以上。
浙公网安备 33010602011771号