zoukankan      html  css  js  c++  java
  • 10.spring声明式事务

    一.回顾事务

    • 事务在项目开发过程非常重要,涉及到数据的一致性的问题,不容马虎!

    • 事务管理是企业级应用程序开发中必备技术,用来确保数据的完整性和一致性。

    1.事务就是把一系列的动作当成一个独立的工作单元,这些动作要么全部完成,要么全部不起作用。

    2.事务四个属性ACID

    1. 原子性(atomicity)

      • 事务是原子性操作,由一系列动作组成,事务的原子性确保动作要么全部完成,要么完全不起作用

    2. 一致性(consistency)

      • 一旦所有事务动作完成,事务就要被提交。数据和资源处于一种满足业务规则的一致性状态中

    3. 隔离性(isolation)

      • 可能多个事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏

    4. 持久性(durability)

      • 事务一旦完成,无论系统发生什么错误,结果都不会受到影响。通常情况下,事务的结果被写到持久化存储器中

    二.Spring中的事务管理

    1.测试事务的一致性

    步骤:(在上一个的博客项目的基础上)

    1. 在UserMapper接口中添加两个方法

      1. addUser:添加用户

      2. deleteUser:删除用户

    2. 在UserMapper.xml中编写SQL语句,故意将delete写成deletes导致出错

    3. 修改UserMapperImpl类

      1. 添加addUser方法

      2. 添加deleteUser方法

      3. 修改selectUser方法,让它先添加一个用户,在删除一个用户最后返回所有用户

    在UserMapper接口中添加两个方法

     1 public interface UserMapper {
     2 
     3     List<User> selectUser();
     4 
     5     //添加用户
     6     int addUser(User user);
     7 
     8     //删除用户
     9     int deleteUser(int id);
    10 }

    在UserMapper.xml中编写SQL语句,故意将delete写成deletes导致出错

    1 <insert id="addUser" parameterType="user">
    2     insert into mybatis.user (id, name, pwd) value (#{id},#{name},#{pwd});
    3 </insert>
    4 
    5 <delete id="deleteUser" parameterType="_int">
    6     deletes from mybatis.user where id = #{id};
    7 </delete>

    修改UserMapperImpl类

     1 public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper {
     2 
     3 
     4     public List<User> selectUser() {
     5         User user = new User(7,"小明","123456");
     6         UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
     7         mapper.addUser(user);
     8         mapper.deleteUser(7);
     9         return mapper.selectUser();
    10     }
    11 
    12     @Override
    13     public int addUser(User user) {
    14         return getSqlSession().getMapper(UserMapper.class).addUser(user);
    15     }
    16 
    17     @Override
    18     public int deleteUser(int id) {
    19         return getSqlSession().getMapper(UserMapper.class).deleteUser(id);
    20     }
    21 }

    直接运行测试程序发现,添加了用户但没有删除用户,事务没有回滚一致性被破坏

    2.Spring的事务管理分为两类:

    • 编程式事务管理(不好,不使用)

      • 将事务管理代码嵌到业务方法中来控制事务的提交和回滚

      • 缺点:必须在每个事务操作业务逻辑中包含额外的事务管理代码

    • 声明式事务管理(好,使用)

      • 一般情况下比编程式事务好用。

      • 将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理。

      • 将事务管理作为横切关注点,通过aop方法模块化。Spring中通过Spring AOP框架支持声明式事务管理。

    3.使用声明式事务管理保证事务的ACID

    步骤:

    1. 修改spring-dao.xml,导入头部约束信息

    2. 修改spring-dao.xml

      1. 添加声明式事务

      2. 添加结合了AOP配置事务通知

      3. 添加结合了AOP配置切点

    修改spring-dao.xml,导入头部约束信息tx

    •  xmlns:tx="http://www.springframework.org/schema/tx" 
    •  http://www.springframework.org/schema/tx 
    •  http://www.springframework.org/schema/tx/spring-tx.xsd 
     1 <beans xmlns="http://www.springframework.org/schema/beans"
     2        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     3        xmlns:tx="http://www.springframework.org/schema/tx"
     4        xmlns:aop="http://www.springframework.org/schema/aop"
     5        xsi:schemaLocation="http://www.springframework.org/schema/beans
     6         http://www.springframework.org/schema/beans/spring-beans.xsd
     7         http://www.springframework.org/schema/aop
     8         http://www.springframework.org/schema/aop/spring-aop.xsd
     9         http://www.springframework.org/schema/tx
    10         http://www.springframework.org/schema/tx/spring-tx.xsd">

    修改spring-dao.xml

     1 <!--4.配置声明式事务
     2         ref:引用我们的数据源
     3     -->
     4     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
     5         <property name="dataSource" ref="dataSource" />
     6     </bean>
     7 
     8     <!--5.结合AOP切入,保证事务的一致性-->
     9     <!--配置事务通知-->
    10     <tx:advice id="txAdvice" transaction-manager="transactionManager">
    11         <tx:attributes>
    12             <!--配置哪些方法使用什么样的事务,配置事务的传播特性
    13                 1.事务的传播特性:多个事务方法相互调用时,事务如何在这些方法间传播
    14                 2.read-only="true":只读不可操作数据
    15                 3.propagation:用于配置事务的传播特性
    16                 4.propagation="REQUIRED":如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是最常见的选择(默认)。
    17             -->
    18             <tx:method name="add" propagation="REQUIRED"/>
    19             <tx:method name="delete" propagation="REQUIRED"/>
    20             <tx:method name="update" propagation="REQUIRED"/>
    21             <tx:method name="query" read-only="true"/>
    22             <tx:method name="*" propagation="REQUIRED"/>
    23         </tx:attributes>
    24     </tx:advice>
    25 
    26     <!--6.配置AOP事务切入
    27         配置切点为mapper包下的所有类和方法,用于保证事务的ACID
    28     -->
    29     <aop:config>
    30         <aop:pointcut id="txPointcut" expression="execution(* ustc.wzh.mapper.*.*(..))"/>
    31         <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
    32     </aop:config>

    此时测试发现没有添加,事务发生了回滚保证了一致性

    将UserMapper.xml中的delete语句修复,依旧执行成功,保证事务一致性

    4.总结:

    为什么需要配置事务?

    • 如果不配置,就需要我们手动提交控制事务;

    • 事务在项目开发过程非常重要,涉及到数据的一致性的问题,不容马虎!

  • 相关阅读:
    MySQL 优化实施方案
    MySQL Replication 主从复制全方位解决方案
    CentOS 7.X 系统安装及优化
    W25Q32的使用
    Word分栏
    转载:STM32之中断与事件---中断与事件的区别
    常见贴片电阻的分类、功率、封装、标注规则
    导线时延
    重装系统流程
    MFC应用程序向导生成的文件
  • 原文地址:https://www.cnblogs.com/zhihaospace/p/12329488.html
Copyright © 2011-2022 走看看