Spring使用AOP实现统一事务处理

我是使用XML配置开发AspectJ框架。
1、 所以!一点要在pom文件引入spring-aspects的配置。
版本自行选择

    <dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-aspects</artifactId>
	    <version>${spring.version}</version> 
	</dependency>

2、 在applicationContext.xml配置数据源和会话工厂和扫描Dao层

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
			<property name="driverClassName" value="com.mysql.jdbc.Driver" />
			<property name="url" value="jdbc:mysql://localhost:3306/early_warning_system?characterEncoding=utf8&amp;useSSL=true" />
			<property name="username" value="root" />
			<property name="password" value="123456" />
			<!-- 最大连接数 -->
			<property name="maxTotal" value="30"/>
			<!-- 最大空闲连接数 -->
			<property name="maxIdle" value="10"/>
			<!-- 初始化连接数 -->
			<property name="initialSize" value="5"/>
	</bean>
	
	<!-- 配置MyBatis工厂,同时指定数据源,并与MyBatis完美整合 -->  
 	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
        <property name="dataSource" ref="dataSource" />  
        <!-- configLocation的属性值为MyBatis的核心配置文件 -->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--mapperLocations 映射器,告诉 MyBatis到哪里去找映射文件-->
        <property name="mapperLocations" value="classpath:mapper/*.xml"/> 
    </bean> 
    
    <!--Mapper代理开发,使用Spring自动扫描MyBatis的接口并装配
 	(Spring将指定包中所有被@Mapper注解标注的接口自动装配为MyBatis的映射接口)  -->      <bean  id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer" >
     	<!-- mybatis-spring组件的扫描器 ,必须写全dao的包名,且只能扫描一个dao包-->
     	<property name="basePackage" value="team.dao"/>
      	<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
     </bean>

3、 配置事务管理的bean

	<bean id= "txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/>
	</bean>

4、 开启事务注解

	<!-- 开启事务注解-->
	<tx:annotation-driven transaction-manager="txManager" />

5、
全局AOP事物,除get,list,select,query开头的方法外,都处在事物当中。“*”表示通配符,这个应该都知道。

        <!-- 全局AOP事物,除get,list,select,query开头的方法外,都处在事物当中  -->
	<tx:advice id="txAdvice" transaction-manager="txManager">
		<tx:attributes>
			<tx:method name="select*" propagation="REQUIRED" read-only="true" />
			<tx:method name="get*" propagation="REQUIRED" read-only="true" />
			<tx:method name="list*" propagation="REQUIRED" read-only="true" />
			<tx:method name="query*" propagation="REQUIRED" read-only="true" />
			<tx:method name="*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception"/>
		</tx:attributes>
	</tx:advice>

这里需要在注意!!
事务属性在tx:method中进行设置,Spring支持对不同的方法设置不同的事务属性,所以可以为一个tx:advice设置多个tx:method,其中name属性指定匹配的方法(这里需要对这些方法名进行约定,如果事务切入点在service上,则最好和Dao的方法命名区分开,也不要使用get set关键字,防止和属性的getter setter发生混淆)

事务有以下几个常用属性:

a.read-only:设置该事务中是否允许修改数据。(对于只执行查询功能的事务,设置为TRUE可以提高事务的执行速度)

b.propagation:事务的传播机制。一般设置为required。可以保证在事务中的代码只在当前事务中运行,防止创建多个事务。

c.isolation:事务隔离级别。不是必须的。默认值是default。

d.timeout:允许事务运行的最长时间,以秒为单位。

e.rollback-for:触发回滚的异常。

f.no-rollback-for:不会触发回滚的异常。

实际开发中,对于只执行查询功能的事务,要设置read-only为TRUE,其他属性一般使用默认值即可。

6、 最后一步,把事务处理织入service的方法中

	<aop:config>    
		<!--配置事务切点 -->    
		<aop:pointcut id="services"    
			expression="execution(* team.service.*.*(..))" />    
		<aop:advisor pointcut-ref="services" advice-ref="txAdvice" />    
	</aop:config>    

注意!"execution(* team.service..(…))"的第一个“*”号后面一定要有一个空格!
否则就会出现错误:

Error creating bean with name 'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Pointcut is not well-formed: expecting 'name pattern' at character position 27
execution(team.service.*.*(..))

版权声明:本文为yxw908186797原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。