- 浏览: 3559523 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (1491)
- Hibernate (28)
- spring (37)
- struts2 (19)
- jsp (12)
- servlet (2)
- mysql (24)
- tomcat (3)
- weblogic (1)
- ajax (36)
- jquery (47)
- html (43)
- JS (32)
- ibatis (0)
- DWR (3)
- EXTJS (43)
- Linux (15)
- Maven (3)
- python (8)
- 其他 (8)
- JAVASE (6)
- java javase string (0)
- JAVA 语法 (3)
- juddiv3 (15)
- Mule (1)
- jquery easyui (2)
- mule esb (1)
- java (644)
- log4j (4)
- weka (12)
- android (257)
- web services (4)
- PHP (1)
- 算法 (18)
- 数据结构 算法 (7)
- 数据挖掘 (4)
- 期刊 (6)
- 面试 (5)
- C++ (1)
- 论文 (10)
- 工作 (1)
- 数据结构 (6)
- JAVA配置 (1)
- JAVA垃圾回收 (2)
- SVM (13)
- web st (1)
- jvm (7)
- weka libsvm (1)
- weka屈伟 (1)
- job (2)
- 排序 算法 面试 (3)
- spss (2)
- 搜索引擎 (6)
- java 爬虫 (6)
- 分布式 (1)
- data ming (1)
- eclipse (6)
- 正则表达式 (1)
- 分词器 (2)
- 张孝祥 (1)
- solr (3)
- nutch (1)
- 爬虫 (4)
- lucene (3)
- 狗日的腾讯 (1)
- 我的收藏网址 (13)
- 网络 (1)
- java 数据结构 (22)
- ACM (7)
- jboss (0)
- 大纸 (10)
- maven2 (0)
- elipse (0)
- SVN使用 (2)
- office (1)
- .net (14)
- extjs4 (2)
- zhaopin (0)
- C (2)
- spring mvc (5)
- JPA (9)
- iphone (3)
- css (3)
- 前端框架 (2)
- jui (1)
- dwz (1)
- joomla (1)
- im (1)
- web (2)
- 1 (0)
- 移动UI (1)
- java (1)
- jsoup (1)
- 管理模板 (2)
- javajava (1)
- kali (7)
- 单片机 (1)
- 嵌入式 (1)
- mybatis (2)
- layui (7)
- asp (12)
- asp.net (1)
- sql (1)
- c# (4)
- andorid (1)
- 地价 (1)
- yihuo (1)
- oracle (1)
最新评论
-
endual:
https://blog.csdn.net/chenxbxh2 ...
IE6 bug -
ice86rain:
你好,ES跑起来了吗?我的在tomcat启动时卡在这里Hibe ...
ES架构技术介绍 -
TopLongMan:
...
java public ,protect,friendly,private的方法权限(转) -
贝塔ZQ:
java实现操作word中的表格内容,用插件实现的话,可以试试 ...
java 读取 doc poi读取word中的表格(转) -
ysj570440569:
Maven多模块spring + springMVC + JP ...
Spring+SpringMVC+JPA
如果要在方法执行前或后或抛出异常后加上一个自己的拦截器,或者一个环绕拦截器,在拦截器中执行一些操作,比如执行一些数据库操作,记录一些信息,这些操作通过调用一个服务类的方法来执行,这个方法也在spring事务管理拦截器的管理之下,那么这个记录方法需要在另一个事务中进行,而不是与被拦截方法在同一个事务中,不然如果被拦截方法抛出异常需要回滚时,所作的记录也会被回滚,当然有时候确实需要同时回滚,那就要放在同一个事务中。
这和自己的拦截器和事务管理的拦截器的执行顺序有一定关系,spring事务管理拦截器是一个环绕通知,在被拦截方法执行前启动事务,执行后完成事务,如果自己的拦截器被spring事务管理拦截器包围在里面,那么在自己的拦截器运行时,spring已经启动了一个事务,如果你的记录信息方法需要与被拦截方法同在一个事务中,将你的记录信息方法的事务传播属性设为默认的REQUIRED就可以了;
如果你记录信息的方法需要单独的一个事务环境,那就要把事务传播属性设为REQUIRES_NEW了,这样spring事务管理器会新建一个事务,并且新建一个session连接,因为一个数据库连接不可能同时有两个事务,记录信息完了提交事务并且把新建的session连接关闭,自己的拦截器退出后继续执行被拦截的方法或它的事务处理。
相反如果自己的拦截器在spring事务管理拦截器的外面,那么记录信息的方法会在一个单独的事务中执行,并提交,不管它的事务传播属性是 REQUIRES_NEW还是REQUIRED,因为与被拦截方法的事务处理没有交叉,并且可以使用同一个session连接如果是 OpenSessionInViewFilter。
所以如果记录信息和被拦截方法要在不同事务中执行,分别提交,那么最好将自己的拦截器
设在spring事务管理器拦截器的外面;如果需要将记录信息和被拦截方法在同一个事务中处理,必须将自己的拦截器被包围在spring事务管理拦截器中,并且记录信息方法的事务传播属性为默认的 REQUIRED。
设置拦截器的执行顺序可以让拦截器处理类实现org.springframework.core.Ordered接口,在spring配置文件的 AOP设置中设定自己的拦截器和spring事务管理拦截器的执行顺序,将自己的拦截的序号排在spring事务管理的前面,就可以将该拦截器放到事务管理拦截器的外面执行了,对于before通知方式会先于事务管理拦截器执行,对于after returning和after和after throwing通知方式会后于事务管理拦截器的执行,对于arount通知方式会包围事务管理拦截器执行。
下面是一个异常拦截器的例子。
有位朋友提到在spring异常拦截器中更新数据不能够提交,做了一下测试,测试环境基本是这样:一个用户登录的功能,spring对 service中的每个方法进行事务管理,在用户检测的service方法上同时加上一个异常拦截器,当用户不存在或密码不正确时用户检测方法会抛出异常,异常拦截器捕获到该异常,同时记录一些日志。
spring配置文件相关:
Java代码 收藏代码
1. <span style="font-size: medium;"> <!-- 事务管理 -->
2. <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
3. <property name="sessionFactory" ref="sessionFactory"></property>
4. </bean>
5.
6. <!-- 事务通知 -->
7. <tx:advice id="txAdvice" transaction-manager="transactionManager">
8. <tx:attributes>
9. <tx:method name="get*" read-only="true"/>
10. <tx:method name="*" propagation="REQUIRES_NEW" rollback-for="Exception"/>
11. </tx:attributes>
12. </tx:advice>
13.
14. <!-- aop代理设置 -->
15. <aop:config proxy-target-class="true">
16. <aop:pointcut id="txPointcut" expression="execution(* com.hbs..*Service.*(..))"/>
17. <aop:pointcut id="logPointcut" expression="execution(* com.hbs.customer..*Service.*(..))"/>
18. <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" order="1"/>
19. <aop:aspect id="logAspect" ref="logInterceptor" order="2" >
20. <aop:after-throwing
21. pointcut-ref="logPointcut"
22. method="serviceIntercept" />
23. </aop:aspect>
24. </aop:config>
25.
26. <!-- log拦截器类 -->
27. <bean id="logInterceptor" class="com.hbs.eventlog.EventLogInterceptor">
28. <property name="service" ref="logService"></property>
29. </bean> </span>
<!-- 事务管理 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 事务通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="*" propagation="REQUIRES_NEW" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
<!-- aop代理设置 -->
<aop:config proxy-target-class="true">
<aop:pointcut id="txPointcut" expression="execution(* com.hbs..*Service.*(..))"/>
<aop:pointcut id="logPointcut" expression="execution(* com.hbs.customer..*Service.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" order="1"/>
<aop:aspect id="logAspect" ref="logInterceptor" order="2" >
<aop:after-throwing
pointcut-ref="logPointcut"
method="serviceIntercept" />
</aop:aspect>
</aop:config>
<!-- log拦截器类 -->
<bean id="logInterceptor" class="com.hbs.eventlog.EventLogInterceptor">
<property name="service" ref="logService"></property>
</bean>
拦截器类:
Java代码 收藏代码
1. <span style="font-size: medium;">public class EventLogInterceptor implements Ordered {
2.
3. private int order = 1;
4.
5. private EventLogService service;
6.
7. public Object serviceIntercept(ProceedingJoinPoint point) throws Throwable{
8. if(point instanceof MethodInvocationProceedingJoinPoint){
9. MethodInvocationProceedingJoinPoint mpoint = (MethodInvocationProceedingJoinPoint)point;
10. //
11. }
12. try {
13. System.out.println("记录日志开始");
14. service.eventLog();
15. System.out.println("记录日志结束");
16. }catch(Exception ex) {
17. ex.printStackTrace();
18. }
19. return null;
20. }
21.
22. public void setOrder(int order){
23. this.order = order;
24. }
25. public int getOrder() {
26. return order;
27. }
28. public EventLogService getService() {
29. return service;
30. }
31. public void setService(EventLogService service) {
32. this.service = service;
33. }
34. }
35. </span>
public class EventLogInterceptor implements Ordered {
private int order = 1;
private EventLogService service;
public Object serviceIntercept(ProceedingJoinPoint point) throws Throwable{
if(point instanceof MethodInvocationProceedingJoinPoint){
MethodInvocationProceedingJoinPoint mpoint = (MethodInvocationProceedingJoinPoint)point;
//
}
try {
System.out.println("记录日志开始");
service.eventLog();
System.out.println("记录日志结束");
}catch(Exception ex) {
ex.printStackTrace();
}
return null;
}
public void setOrder(int order){
this.order = order;
}
public int getOrder() {
return order;
}
public EventLogService getService() {
return service;
}
public void setService(EventLogService service) {
this.service = service;
}
}
service方法中的事务传播属性都设为要求新建事务,spring事务管理切面拦截器的order设为1,而log拦截器的order设为2,这意味着这两个要同时执行时,先执行事务拦截器,后执行log拦截器,由于事务管理是一个环绕通知(around),实际上是log拦截器被包围在事务管理拦截器中。
从中可以看出,log异常拦截器在用户登录的事务回滚之前截获异常,在记录日志时,日志记录的service方法也在spring的事务管理之下,用户登录的事务还没有结束,根据REQUIRES_NEW特性,spring会新开一个事务,这时原来的数据库连接已经在一个事务中,一个连接不可能同时有两个事务,所以同时新创建一个session连接(虽然我使用了OpenSessionInViewFilter,并且session是单例的),日志记录就在新建的事务和session中进行,完了提交,并且会把新建的session连接关闭。
然后继续进行被中断的用户登录的事务管理操作,由于抛异常spring将用户登录的事务回滚。
这样能够实现预想的功能,但是如果我去掉指定的REQUIRES_NEW,那么log记录的操作会继续在用户登录的事务中进行,最后会被一起回滚。
如果把事务管理的order设为2,log拦截器的order设为1,也就是log拦截器在事务管理拦截器的外面,会在事务管理拦截器前后执行完了再执行log的异常拦截器。
可以看出,用户登录的事务和日志记录的事务是前后两个不相关的事务,并且在日志记录事务中并不需要新建session连接,而是直接用在 OpenSessionInViewFilter中创建的session。实际上这时也并不需要将propagation设为REQUIRES_NEW,使用默认的REQUIRES也照样能够正常工作。
所以应该将该异常拦截器设在事务管理拦截器的外面,即使用Order接口排在前面。
(本文章转载来自http://endual.iteye.com/admin/blogs/new)。博客作者改编了题目
发表评论
-
spring mvc 文件上传
2015-12-16 15:56 1032http://cmao.iteye.com/blog/2264 ... -
spring mvc 控制文件大小
2015-03-08 23:49 1191http://19950603.blog.51cto.com/ ... -
spring data jpa 分页
2014-08-28 23:27 13489public Page<Task> getUser ... -
spring mvc maven 视频
2013-10-17 03:24 1259http://www.verycd.com/topics/29 ... -
pom 创库
2013-09-20 01:13 13061, spring 和hibernate要哪些包,这个要LZ ... -
服务器推送技术可以看看
2013-09-17 16:38 769activeMq或者comet4j试试 -
spring mvc jpa 引入包中的实体类
2013-09-16 16:22 3038http://www.iteye.com/topic ... -
spring mvc 定时器
2013-09-11 15:44 1210http://fhqllt.iteye.com/blog/43 ... -
spring mvc 作业调度
2013-09-11 15:42 1109http://tonyaction.blog.51cto.co ... -
spring mvc 发生邮件
2013-09-11 15:38 1183http://blog.csdn.net/geloin/art ... -
spring mvc 文件的上传和下载
2013-09-11 15:32 1429http://blog.csdn.net/yiyuhanmen ... -
Spring JPA 无法扫描多JAR包中@Entity类的有关问题
2013-08-26 23:20 2569Spring JPA 无法扫描多JAR包中@Entity ... -
Spring+SpringMVC+JPA
2013-08-21 16:17 27782SpringMVC是越来越火,自己也弄一个Spring+ ... -
spring mvc 权限管理项目 shiro
2013-08-20 23:37 1441https://github.com/ketayao -
spring mvc 整合shiro
2013-08-20 23:13 1289http://www.th7.cn/Program/java/ ... -
spring data jpa 和spring mvc
2013-08-20 22:10 1412http://www.cnblogs.com/luxh/arc ... -
spring mvc 乱码
2013-08-20 12:19 1297因为使用spring mvc的时候,已经在web.xml中设 ... -
Spring3.2.2_自动装配
2013-08-16 08:57 1912Spring3.2.2_自动装配 ... -
Spring 3 MVC: Tiles Plugin Tutorial With Example In Eclipse By Viral Patel on Ju
2013-08-14 17:24 2557Spring 3 MVC: Tiles Plugin T ... -
spring data jpa 采用内存数据库
2013-08-13 15:43 2979# The default database is H2 me ...
相关推荐
在Spring框架中,AOP(面向切面编程)是一种强大的工具,它允许程序员将关注点分离,例如日志记录、事务管理、权限检查等,从核心业务逻辑中解耦出来。本篇主要探讨的是如何利用Spring AOP的注解来实现这些功能,...
AOP提供了一种模块化系统的方式,将关注点分离为独立的“切面”,这些切面可以包含业务逻辑的多个方面,如日志、事务管理、性能监控等。切点(Pointcut)定义了这些关注点插入到代码中的位置,而通知(Advice)则...
在Spring AOP中,concern指的是应用程序中的业务逻辑代码,而cross-cutting concern是横切关注点,如日志记录、事务管理等,这些关注点贯穿多个业务逻辑。 44、AOP有哪些实现方式? AOP可以通过以下几种方式实现: ...
这种代理类可以拦截调用,并在调用前后执行额外的操作,如日志记录、事务管理等。Java的`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口是实现动态代理的核心组件。 2. 创建动态代理 要...
2. **AOP**:阐述AOP的概念,介绍通知类型(前置、后置、环绕、异常和最终通知),并举例说明如何实现日志记录或事务管理。 3. **Spring MVC**:Spring MVC是Spring框架的一部分,用于构建Web应用。讨论...
2. **面向切面编程(AOP)**:Spring提供AOP支持,实现事务管理、日志记录等功能。 3. **容器**:Bean工厂和ApplicationContext是Spring的两大容器,负责管理Bean的生命周期。 4. **Spring MVC**:Spring的MVC模块,...
Spring是核心的依赖注入(DI)和面向切面编程(AOP)框架,它管理着应用中的对象及其依赖关系,提供了事务管理、数据源配置等功能。在本示例中,Spring将作为整个框架的基础,负责配置、管理其他组件以及业务逻辑。 ...
Spring的AOP功能则允许开发者定义切面,实现如日志记录、事务管理等通用功能,无需在业务代码中重复编写。 SpringMVC作为Spring的Web MVC模块,负责接收HTTP请求,调度控制器,处理视图以及与模型的交互。它提供了...
这通常用于实现AOP(面向切面编程)的概念,如日志、事务管理、性能监控等。下面将详细讲解动态代理的原理、实现方式以及如何通过反射来创建动态代理。 首先,了解动态代理的基本概念。在Java中,动态代理基于JDK的...
- **spring-mybatis.xml**:配置Spring与MyBatis的整合,包括数据源、事务管理器、SqlSessionFactory等。 - **spring-mvc.xml**:配置SpringMVC,包括视图解析器、拦截器等。 ##### 3.3 数据库连接配置 (`jdbc....
Spring的依赖注入(DI)和面向切面编程(AOP)特性使得代码更加解耦,易于测试和维护。在SSH整合中,Spring主要负责业务逻辑的协调和数据访问的管理。 2. Struts框架: Struts是MVC(Model-View-Controller)设计...
AOP是Spring提供的一种处理横切关注点(如日志、事务管理)的技术。在项目中,可能包含自定义的切面,通过定义通知(advice)和切入点(pointcut),实现代码的解耦,使得业务逻辑更加清晰。 4. **数据访问** ...
这在处理如日志、事务管理、性能监控等跨切面关注点时非常有用。 `Proxy`类是Java动态代理的工厂,它提供了`newProxyInstance()`方法,用于创建代理对象。这个方法需要三个参数:目标接口的类加载器、目标接口数组...
Spring是一个全面的企业级应用开发框架,它提供了依赖注入(DI)、面向切面编程(AOP)、事务管理、数据访问/集成、MVC等核心功能。在MVC模式中,Spring MVC作为控制器,负责调度请求,并与模型和视图进行交互。...
- `applicationContext.xml`:这个文件通常包含更广泛的应用范围的配置,比如数据源、事务管理、DAO和Service层的Bean定义。 4. **集成配置**: - 在SSH集成项目中,通常还需要一个或多个额外的配置文件来协调这...
- MyBatis:SQL映射、动态SQL、事务管理。 - Hibernate:对象关系映射、缓存机制。 - Struts:MVC架构、Action类、拦截器。 3. **中间件**: - 消息队列:RabbitMQ、Kafka、ActiveMQ,如何实现异步处理和解耦。...
- **封装、继承和多态**:理解这三个面向对象的基本特性,并能举例说明。 - **构造器**:了解构造函数的作用,构造器的重载和实例化过程。 - **访问修饰符**:private, protected, public, default的使用场景及其...
- **面向切面编程**:利用AOP实现日志记录、事务管理等功能。 - **声明式事务管理**:简化事务管理的配置和使用。 #### SpringMVC框架 - **请求处理**:使用@Controller注解定义控制器类,@RequestMapping注解映射...
- **AOP**:介绍切面编程的基本概念,以及如何实现方法拦截。 以上这些知识点是Java开发人员必须掌握的基础内容,同时也是SOHU等公司面试时可能会涉及的重要领域。准备这些题目有助于提升Java程序员的技术深度和...