写点什么

SpringMVC(六、声明式事务控制)

作者:
  • 2022 年 8 月 12 日
    河南
  • 本文字数:2972 字

    阅读完需:约 10 分钟

1、编程式事务控制相关对象

1)PlatformTransactionManager

​ PlatformTransactionManager 接口是 spring 的事务管理器,它里面提供了我们常用的操作事务的方法:


回滚事务


​ PlatformTransactionManager 是接口类型,不同的 Dao 层技术则有不同的实现类,例如:


​ Dao 层技术是 jdbc 或 mybatis 时:org.springframework.jdbc.datasource.DataSourceTransactionManager


​ Dao 层技术是 hibernate 时 org.springframework.orm.hibernate5.HibernateTransactionManager

2)TransactionDefinition

​ TransactionDefinition 是事务的定义信息对象,里面有如下方法:


  1. 事务隔离级别

  2. 设置隔离级别,可以解决事务并发产生的问题,如脏读、不可重复读和虚读。

  3. ISOLATION_DEFAULT

  4. ISOLATION_READ_UNCOMMITTED

  5. ISOLATION_READ_COMMITTED

  6. ISOLATION_REPEATABLE_READ

  7. ISOLATION_SERIALIZABLE

  8. 事务传播行为

  9. REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。一般的选择(默认值)

  10. SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行(没有事务)

  11. MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常

  12. REQUERS_NEW:新建事务,如果当前在事务中,把当前事务挂起。

  13. NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起

  14. NEVER:以非事务方式运行,如果当前存在事务,抛出异常

  15. NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行 REQUIRED 类似的操作

  16. 超时时间:默认值是-1,没有超时限制。如果有,以秒为单位进行设置

  17. 是否只读:建议查询时设置为只读

3)TransactionStatus

TransactionStatus 接口提供的是事务具体的运行状态,方法介绍如下:


2、基于 XML 的声明式事务控制

1)什么是声明式事务控制?

​ Spring 的声明式事务顾名思义就是采用声明的方式来处理事务。这里所说的声明,就是指在配置文件中声明 ,用在 Spring 配置文件中声明式的处理事务来代替代码式的处理事务。

2)声明式事务处理的作用

​ 事务管理不侵入开发的组件。具体来说,业务逻辑对象就不会意识到正在事务管理之中,事实上也应该如 此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要改变事务管理策划的话, 也只需要在定义文件中重新配置即可。


​ 在不需要事务管理的时候,只要在设定文件上修改一下,即可移去事务管理服务,无需改变代码重新编译 ,这样维护起来极其方便。


注意:Spring 声明式事务控制底层就是 AOP。

3)声明式事务控制的实现

声明式事务控制明确事项:


谁是切点?
谁是通知?
配置切面?
复制代码


(1) 引入 tx 命名空间



(2) 配置事务增强


  <!--配置平台事务管理器-->    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">        <property name="dataSource" ref="dataSource"/>    </bean>
<!--通知 事务的增强--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!--设置事务的属性信息的--> <tx:attributes> <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" readonly="false"/> <tx:method name="save" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/> <tx:method name="findAll" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/> <tx:method name="update*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/> <tx:method name="*"/> </tx:attributes> </tx:advice>
复制代码


(3) 配置事务 AOP 织入


  <!--配置事务的aop织入-->    <aop:config>        <aop:pointcut id="txPointcut" expression="execution(* com.xmp.service.impl.*.*(..))"/>        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>    </aop:config>
复制代码


(4) 测试事务控制转账业务代码


 public void transfer(String outMan, String inMan, double money) {        accountDao.out(outMan,money);        int i = 1/0;        accountDao.in(inMan,money);    }
复制代码
4)切点方法的事务参数的配置
<!--事务增强配置--><tx:advice id="txAdvice" transaction-manager="transactionManager">  <tx:attributes>    <tx:method name="*"/>  </tx:attributes></tx:advice>
复制代码


其中, 代表切点方法的事务参数的配置,例如:


​ name:切点方法名称


​ isolation:事务的隔离级别


​ propogation:事务的传播行为


​ timeout:超时时间


​ read-only:是否只读

3、 基于注解的声明式事务控制

1、编写 AccoutDao
import com.xmp.dao.AccountDao;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.stereotype.Repository;
@Repository("accountDao")public class AccountDaoImpl implements AccountDao {
@Autowired private JdbcTemplate jdbcTemplate;
public void out(String outMan, double money) { jdbcTemplate.update("update account set money=money-? where name=?",money,outMan); }
public void in(String inMan, double money) { jdbcTemplate.update("update account set money=money+? where name=?",money,inMan); }}
复制代码
2、编写 AccoutService
package com.xmp.service.impl;
import com.xmp.dao.AccountDao;import com.xmp.service.AccountService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Isolation;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;
@Service("accountService")@Transactional(isolation = Isolation.REPEATABLE_READ)public class AccountServiceImpl implements AccountService {
@Autowired private AccountDao accountDao;
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED) public void transfer(String outMan, String inMan, double money) { accountDao.out(outMan,money); int i = 1/0; accountDao.in(inMan,money); }
//@Transactional(isolation = Isolation.DEFAULT) public void xxx(){}}
复制代码
3、编写配置文件
  <!--组件扫描-->    <context:component-scan base-package="com.xmp"/>        <!--事物的注解驱动-->    <tx:annotation-driven transaction-manager="transactionManager"/>
复制代码
4、注解配置声明式事务控制解析

​ ① 使用 @Transactional 在需要进行事务控制的类或是方法上修饰,注解可用的属性同 xml 配置方式,例如隔离 级别、传播行为等。


​ ② 注解使用在类上,那么该类下的所有方法都使用同一套注解参数配置。


​ ③ 使用在方法上,不同的方法可以采用不同的事务参数配置。


​ ④ Xml 配置文件中要开启事务的注解驱动

发布于: 刚刚阅读数: 3
用户头像

关注

在校大三学生一枚 2022.08.02 加入

喜欢学习编程,擅长技术栈JAVA

评论

发布
暂无评论
SpringMVC(六、声明式事务控制)_开源_斯_InfoQ写作社区