1.本设计采用springMVC+Hibernate ,事务控制在Service层,直接上代码
2.web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>HiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter </filter-class> </filter> <filter-mapping> <filter-name>HiddenHttpMethodFilter</filter-name> <servlet-name>spring</servlet-name> </filter-mapping> <filter> <filter-name>openSessionInViewFilter</filter-name> <filter-class> org.springframework.orm.hibernate4.support.OpenSessionInViewFilter </filter-class> </filter> <filter-mapping> <filter-name>openSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>springMVC3</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springMVC3</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <session-config> <session-timeout>20</session-timeout> </session-config> <display-name>MeatBall</display-name> <welcome-file-list> <welcome-file>/admin/homepage</welcome-file> </welcome-file-list> </web-app>
2. applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:task="http://www.springframework.org/schema/task" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <context:annotation-config /> <!-- 扫描Controller,Service,Reponsitory --> <context:component-scan base-package="com.zxd" > <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />
</context:component-scan> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:resources.properties</value> </list> </property> </bean> <!-- 数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${connection.driver_class}" /> <property name="jdbcUrl" value="${connection.url}" /> <property name="user" value="${connection.username}" /> <property name="password" value="${connection.password}" /> <property name="maxPoolSize" value="80" /> <property name="minPoolSize" value="1" /> <property name="initialPoolSize" value="1" /> <property name="maxIdleTime" value="20" /> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="packagesToScan"> <list> <value>com.zxd.project.goods.model</value> <value>com.zxd.project.user.model</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.jdbc.batch_size">20</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> </bean> <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="create*" propagation="REQUIRED" /> <tx:method name="insert*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" isolation="READ_COMMITTED"/> <tx:method name="upload*" propagation="REQUIRED" /> <tx:method name="merge*" propagation="REQUIRED" /> <tx:method name="del*" propagation="REQUIRED" /> <tx:method name="remove*" propagation="REQUIRED" /> <tx:method name="clear*" propagation="REQUIRED" /> <tx:method name="put*" propagation="REQUIRED" /> <tx:method name="use*" propagation="REQUIRED" /> <tx:method name="get*" propagation="REQUIRED" read-only="true" /> <tx:method name="load*" propagation="REQUIRED" read-only="true" /> <tx:method name="count*" propagation="REQUIRED" read-only="true" /> <tx:method name="find*" propagation="REQUIRED" read-only="true" /> <tx:method name="after*" propagation="REQUIRED" read-only="true" /> <tx:method name="list*" propagation="REQUIRED" /> <tx:method name="pag*" propagation="REQUIRED" /> <tx:method name="query*" propagation="REQUIRED" read-only="true" /> </tx:attributes> </tx:advice> <!-- 只对业务逻辑(service)层实施事务 --> <aop:config> <aop:pointcut id="txPointcut" expression="execution(* com.zxd..service.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" /> </aop:config> </beans>
3.application-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sec="http://www.springframework.org/schema/security" xmlns:context="http://www.springframework.org/schema/context" xmlns:task="http://www.springframework.org/schema/task" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd "> <!-- 注解驱动 --> <mvc:annotation-driven> <mvc:message-converters> <!-- 中文编码 --> <bean class="com.zxd.common.util.UTF8StringHttpMessageConverter" /> </mvc:message-converters> </mvc:annotation-driven> <!-- 定时任务驱动 --> <task:annotation-driven/> <context:component-scan base-package="com.zxd" > <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/> </context:component-scan> <!-- 视图解析 --> <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver"> <!-- 返回的视图模型数据需要经过jstl来处理 --> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/jsp" /> <property name="suffix" value=".jsp" /> </bean> <!-- 对静态资源文件的访问 不支持访问WEB-INF目录 --> <mvc:default-servlet-handler /> <!-- 对静态资源文件的访问 支持访问WEB-INF目录 --> <mvc:resources location="/static/" mapping="/static/**" /> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!--one of the properties available;the maximum file size in bytes --> <property name="maxUploadSize" value="500000000" /> </bean> <bean id="stringConverter" class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/plain;charset=UTF-8</value> </list> </property> </bean> <!-- 输出对象转JSON支持 --> <bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <ref bean="stringConverter"/> <ref bean="jsonConverter" /> </list> </property> </bean> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean id="ErrorInterceptor" class="com.zxd.common.interceptors.GlobleErrorInterceptor"/> </mvc:interceptor> </mvc:interceptors> </beans>
4.以下为详解。
首先通过web.xml解析applicationContext(此为父容器)
<!-- 扫描Controller,Service,Reponsitory --> <context:component-scan base-package="com.zxd" > <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service" />
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository" />
</context:component-scan>
在这段代码中,首先会吧com.zxd下的Controller,Service,Repository,注入到父容器中(可以不写Service,Repository,Controller,直接写成
<context:component-scan base-package="com.zxd" />也是可以的,Component-scan中就包含Service,Repository,Controller这一些注解),父容器是有事务控制的。 然后再来看
<context:component-scan base-package="com.zxd" > <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/> </context:component-scan>这段代码,在加载applicationContext-servlet.xml中一定要除去Service层,防止再次注入到父容器中,这个applicationContext-servlet是不具备事务控制的。 下面,摘一段控制台打印信息。
可以看到创建了食物,而且我在update*的isolation处改变了隔离级别。事务配置成功。那么下面再来看一下失败的。
在这里,我们可以看到,rollingBack,事务回滚成功。
如果您还想更深入了解,例如源码等,请捐赠我任意一笔金额。谢谢