spring事务管理之声明式事务管理详解

spring为我们提供了两种的事务管理,编程式事务管理和声明式事务管理,因为spring提倡使用声明式事务管理,所以笔者本身也具体学习研究和应用声明式事务,这里只详细谈谈声明式事务,而编程式事务就一句概括;

编程式事务:使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。

声明式事务:spring的声明式事务的实现方式有两种,一种是基于AOP切面实现声明式事务,而第二种是基于注解@ Transacitional实现,但是两种都需要在sprig的xml配置才能启动事务管理;本篇文章先讲基于注解Transacitional的声明式事务的实现,这里先看下xml配置文件是怎么配置的,代码如下:

<tx:annotation-driven  transaction-manager="txManager" proxy-target-class="true"/>
<!-- 配置事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!--事物管理的对象,通常直接是数据库-->
    <property name="dataSource" ref="dataSource" />
</bean>

其中,tx:annotation-driven标签表示开启事务管理,属性具体介绍如下:

transaction-manager:表示索引引用的事务管理器,通常直接用spring内置的事务管理器即可,所以我们还需要获取到spring的事物管理类的对象,如上如所示,用在spring配置文件中实例化datasourceTrasactionManager,其中dataSource为事务管理的数据源,通常为数据库的数据源;

proxy-target-calss:表示为那些注解了Transactional的类或方法开启事务代理,但是只对代理模式有效,而什么又叫代理模式呢?其实只要通过spring IOC管理的bean就是代理模式了,而new出来的对象就不属于代理模式;该属性值为boolean类型

默认proxy-target-calss =  false:表示开启JDK代理,该代理模式只对那些实现了接口的类开启JDK代理,所以这时候注解了Transactional的方法或类的事务管理才其作用,而那些没有实现接口的类,即使启用了Transactional注解,也不会起事务作用,所以读者也是遇到了事务不起作用的话,就需要排查下是否开启JDK代理,而不是使用下面的CGLIB代理;

当proxy-target-calss = true:表示强制使用CGLIB代理,该代理模式表示基于类的代理模式被创建,无论有没有实现接口。只要类或方法有启用了Transactional注解,就启动了事务管理;也就是对所有的controller和service以及工具类都起作用,sprnig会自动识别代理的对象,在JDK和CGLIB两种代理模式之间切换;

注意一点:如果要实现controller的事务管理,需要将该配置文件配置在controller对应的mvc配置文件,否则,你有会发现你开开启了CGLIB代理模式,所有地方的事务管理都生效了,而controller的事务管理却没起作用;至于为什么mvc要单独配置一份,这涉及到spring  IOC管理的bean的创建流程,笔者对spring IOC的容器初始化过程还不是很清楚,所以这里不做介绍,读者可以查阅下spring IOC相关的源代码或文章;

接下来就是注解@Transactional的使用:

该注解有以下几种属性:propagation,isolation,readOnly,timeout,rollbackFor,rollbackForClassname,noRollbackFor,noRollbackForClassname,各个含义如下:

propagation :表示事务的传播行为,默认值为REQUIRED,spring有7种的事务传播机制;关于这7种的传播机制内容比较多,笔者后面会专门写一篇《关于spring事务的7种传播机制详解》,这里就暂时一笔盖过;

isolation :表示事务的隔离级别,spring有5种的事务隔离级别,这里笔者也是后面专门写一篇《关于spring事务的5种隔离级别》做具体介绍

timeout :表示事务超时时间,默认为-1,表示永不超时

rollbackFor,rollbackForClassname,noRollbackFor,noRollbackForClassname:这4个含义就是字面意思,表示那些异常类或者异常类名要回滚,这里不做过多介绍,通常只需要默认值即可;

接下来就看下该注解的具体使用,使用起来很简单,如下:

 

@Transactional(propagation = Propagation.REQUIRED)
public int addUser(CourseDto dto) {
    User userModel = mapper.map(dto,User.class);
    int result = userDao.getSqlSession().insert("addUser",userModel);
     //批量插入数据
  userMarkerDao.getSqlSession().insert("addUserMarkerBatch",userMarkerList);
    return result;
}

 

在方法级别上配置事务注解,事务传播机制为:REQUIRED,表示当前方法必须在一个具有事务的上下文中运行。如果当前没有事务,就新建一个事务;如果已经存在一个事务,就加入到这个事务中;该值也是默认值;

这样简单的例子就完成了事务的管理;当userMarekerDao插入数据失败之后,则之前插入的用户的数据就会执行回滚操作;

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值