SSM系列7_进阶_声明式事务

4 篇文章 0 订阅
2 篇文章 0 订阅

1 何为事务

事务:一批数据,要么同时成功保存到数据库,要么同时提交到数据库失败
Mybatis中需要手动操作进行commit与rollback
Spring 提供了声明式事务处理方法

2 声明事务的配置

2.1 应用上下文开启事务配置

applicationContext.xml 中需要增加如下设置

2.1.1 头部增加

在这里插入图片描述

xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd

2.1.2 增加bean

注意:ref="dataSource"这里引用的是你自己项目里的数据源,数据源id是什么这里就写什么
在这里插入图片描述

<!--事务管理器transactionManager提供了声明式事务的支持,在程序成功提交,抛出"运行时异常"时进行回滚-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
</bean>
<!--开启注解形式的声明式事务-->
<tx:annotation-driven transaction-manager="transactionManager"/>

3 声明式事务如何使用

3.1 示例

比如说要初始化多条数据,要求插入时必须全部成功,或者全部失败
准备好各个层所用的方法

3.1.1 mapper xml层

在这里插入图片描述

<insert id="insert" parameterType="com.zhangyx.ssm.entity.Goods">
        INSERT INTO `babytun`.`t_goods`(`title`, `sub_title`, `original_cost`, `current_price`, `discount`, `is_free_delivery`, `category_id`)
        VALUES (#{goods.title}, #{goods.subTitle}, #{goods.originalCost}, #{goods.currentPrice}, #{goods.discount}, #{goods.isFreeDelivery}, #{goods.categoryId})
        <selectKey resultType="int" keyProperty="goodsId" order="AFTER">
            select last_insert_id()
        </selectKey>
</insert>

3.1.2 mapper class 层

int insert(Goods goods);

3.1.3 Service层

//初始化十条数据
public void initGoods(){
	for (int i =0;i < 10 ;i++){
	Goods goods = new Goods();
	goods.setCategoryId(i);
	goods.setCurrentPrice(10f*2);
	goods.setDiscount(10f);
	goods.setIsFreeDelivery(i);
	goods.setOriginalCost(20f);
	goods.setSubTitle("模拟初始化数据");
	goods.setTitle("模拟初始化数据");
	goodsMapper.insert(goods);
	}
}

3.1.4 测试

是写测试还是网页调测试自己选择
如果在i=3的时候,程序报错了,这里模拟程序出现异常,代码加入

if(i==3){
    throw new RuntimeException(“RuntimeException”);
}

模拟程序出错

//初始化十条数据
public void initGoods(){
	for (int i =0;i < 10 ;i++){
	if(i==3){
	    throw new RuntimeException(“RuntimeException”);
	}
	Goods goods = new Goods();
	goods.setCategoryId(i);
	goods.setCurrentPrice(10f*2);
	goods.setDiscount(10f);
	goods.setIsFreeDelivery(i);
	goods.setOriginalCost(20f);
	goods.setSubTitle("模拟初始化数据");
	goods.setTitle("模拟初始化数据");
	goodsMapper.insert(goods);
	}
}

页面请求报如下错
在这里插入图片描述
我们看一下数据库数据
在这里插入图片描述
看到结果,只插入了三条数据,如果这是银行转账,岂不是很危险
所以这个时候就用到了事务,Spring为我们提供了声明式事务,不用再用Mybatis的手动rollback操作
一般声明式事务在service层使用,直接使用在类上或者方法上,在方法上只在此方法内起作用,在类上使用则该类内的方法全部开启事务

3.2 方法上使用

在这里插入图片描述

3.3 类上使用

在这里插入图片描述

3.4 测试

程序报错,并且自动进行了回滚,数据也没有插入到数据库,测试成功
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4 设置不使用事务

如果事务放到了类上,但是我们有类中有查询方法,查询方法是不需要使用事务的,可以使用propagation = Propagation.NOT_SUPPORTED设置不使用事务,并且设置为只读的readOnly=true
在这里插入图片描述

5 事务作用域

上面我们使用了throw new RuntimeException()异常模拟了,程序出现异常的情况,如果程序不是出现了这个异常,而是出现了其他的异常呢,例如说抛出了ParseException(“”,1),我们来测试看一下
在这里插入图片描述
我们看到虽然异常抛出了,但是也有数据数据也进入了数据库
在这里插入图片描述
在这里插入图片描述
那么我们可以知道,@Transactionnal只对 运行时异常(RuntimeException)起作用,那么如果出现别的问题应该怎么办呢,此时只需要指定此注解起作用的类@Transactional(rollbackFor = Exception.class)即可

6 指定rollbackFor

指定rollbackFor才是此注解的真正用法
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值