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

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

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

声明式事务:spring的声明式事务是基于注解及sprig的xml配置完成事务管理的;这里先看下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的事物管理类的对象,如上如所示,用<bean>标签引进datasourceTrasactionManager,其中dataSource为事务管理的对象,通常为数据库的数据源;

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

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

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

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

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

扫描二维码关注公众号,回复: 2180096 查看本文章

该注解有以下几种属性: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插入数据失败之后,则之前插入的用户的数据就会执行回滚操作;

相关文章:

关于spring事务的7种传播机制详解》:待补充;

关于spring事务的5种隔离级别》:待补充;


猜你喜欢

转载自blog.csdn.net/llf_1241352445/article/details/79831031
今日推荐