实验目的

1.实现超市订单系统中供应商表的添加操作
2.配置事务管理器组件
3.在Spring配置文件中使用tx和aop命名空间下的标签配置声明式事务
4.修改上例,使用注解的方式配置声明式事务

实验学时及环境

a) 操作系统:Windows
b) 实验设备:普通PC机。

实验步骤

xml方法配置对事务进行增强

xml文件配置步骤

(1) 导入tx和aop命名空间

<?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:mybatis="http://mybatis.org/schema/mybatis-spring"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>

(2) 定义事务管理器bean,并为其注入数据源bean

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--控制数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>

(3) 通过<tx:advice />配置事务增强,绑定事务管理器,设定事务属性,为不同业务方法指定具体的事务规则

<tx:advice id="txAdvice" transaction-manager="txManager">
        <!-- <tx:attributes>标签定制事务属性-->
        <!--定义属性,声明事务规则-->
        <tx:attributes>
            <!--<tx:method>对不同方法设置不同属性-->
            <!--name用于指定匹配方法-->
            <!--propagation用于指定事务传播机制-->
            <!--所有方法都是事务的方法 name用于指定匹配方法,-->
            <tx:method name="find*" propagation="SUPPORTS"/>
            <tx:method name="add*" propagation="REQUIRED"/>
            <tx:method name="del*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="*" propagation="REQUIRED"/>
            <!--以get开始的所有方法  read-only事务是否为只读 -->
            <tx:method name="get*" read-only="true"/>
        </tx:attributes>
    </tx:advice>

(4) 配置切面,将事务增强与方法切入点结合

<aop:config>
        <!--定义切入点-->
        <!--service下的所有类的所有方法,都采用事务-->
        <aop:pointcut id="txPoint" expression="execution(* com.wxl.smbms.service..*(..))" />
        <!--将事务增强与切入点结合-->
        <!--配置事务增强-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
    </aop:config>

Service层事务方法为

@Override
	public boolean add(Provider provider) {
		boolean flag = false;
		int bool= providerMapper.insert(provider);
		if(bool<0){
			flag = true;
			System.out.println("add success!");

		}else {
			System.out.println(bool+"add failed!");
		}
		int i;
		i=1/0;
		System.out.println("add success!");
		return flag;
	}

测试方法

@Test
    public void testAOPProvider(){
        Provider provider=new Provider();
        provider.setProCode("BJ_GYS001");
        provider.setProName("北京三木堂商贸有");
        provider.setProAddress("北京市丰台区育芳园北路");
        provider.setProContact("52555");
        provider.setProDesc("、五粮液、郎酒、酒鬼酒、泸州老窖、赖茅酒、法国红");
        provider.setProFax("0755-67772341");
        provider.setCreatedBy(1L);
        provider.setCreationDate(new Date());
        boolean result=providerService.add(provider);
        System.out.println("返回:"+result);
    }

测试结果及分析


测试结果显示控制台输出add success!,但是报错java.lang.ArithmeticException: / by zero,因为在service方法中故意添加了“i=1/0”。检查数据库是否插入成功。

发现,数据并没有插入到数据库,说明事务进行了数据回滚

注解方式

Xml配置

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--控制数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <tx:annotation-driven transaction-manager="txManager"/>

Service配置注解

@Transactional
@Service
public class ProviderServiceImpl implements ProviderService {
	@Autowired
	ProviderMapper providerMapper;
	@Override
	@Transactional(propagation = Propagation.SUPPORTS)
	public boolean add(Provider provider) {
		boolean flag = false;
		int bool= providerMapper.insert(provider);
		if(bool<0){
			flag = true;
			System.out.println("add success!");

		}else {
			System.out.println(bool+"add failed!");
		}
		int i;
		i=1/0;
		System.out.println("add success!");
		return flag;
	}
}


测试结果

结果分析:

(1)Xml中配置分析
<tx:annotation-driven transaction-manager=“txManager”/>的作用:
tx:annotation-driven/>标签就是支持使用(@Transactional)注解来配置事务。

(2)Service方法注解分析
1)@Transactional的作用:
添加该注解后,即可为该类的所有注解统一添加事务
2)@Transactional(propagation = Propagation.SUPPORTS)的作用:
单独为该方法配置不同的事务规则
3)@Transactional的默认值
(propagation)事务传播默认值是Propagation.REQUIRED
(isolation)事务隔离级别默认值是Isolation.DEFAULT
(rollbackFor)任何RuntimeException将触发事务回滚,但是checked Exception不会出发事务回滚