最近在搭建一个springmvc+hibernate+spring框架的时候,发现hibernate的Session操作delete和update不行了,根本就无效,要执行session.flush()才能执行sql语句。session原理:其实我们执行session更新和删除操作的时候,不会立即执行,要执行flush才可执行。但是如果配置了事务管理,这件事就可以交给事务管理器去完成,在事务提交的时候执行自动执行flush语句。
为了确定是否是事务问题,我把事务配置注释掉了,问题还是原来那样子,所以我就一直去更改事务管理配置,更改了五种事务管理方法。一次又一次的检查,但是还是无效。确定了事务问题,但是事务配置有没有错误,奔溃了。
错误原因:是配置出现了问题:
-
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath*:config/spring/*.xml</param-value>
- </context-param>
- <servlet>
- <servlet-name>springMVC</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath*:config/spring/spring-mvc.xml</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
一开始就加载了所以配置,后面servlet初始化的时候又加载了springmvc.xml。这本身就是不合理了的。但是主要问题不是这个。问题是:spring-mvc.xml由servlet加载的时候,
-
- <context:component-scan base-package="com.tgb" />
如果一开始就注册所有的注解,那么,遇到@service的时候,事务配置就很可能无效,尤其是@Transactional一定失效。所以事务配置就不管用。
解决方案:分开加载控制器和其他注解。控制器的注解由springmvc.xml加载,
-
- <context:component-scan base-package="com.tgb.controller" />
spring配置文件中,加载其他注解:
- <context:component-scan base-package="com.tgb.*">
- <context:exclude-filter type="regex" expression=".*controller$"/>
- </context:component-scan>
-
- <tx:annotation-driven transaction-manager="transactionManager" />
这样,事务配置就能起作用了。