• Spring 学习(八)事务管理


    1. 事务

    1.1 事务的 ACID 原则

    • 数据库事务(transaction)是访问并可能操作各种数据项的一个数据库操作序列。事务必须满足 ACID 原则——即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

      • 原子性指事务是数据库工作的最小单位,一个事务中的所有操作要么全部成功提交,要么全部失败回滚。
      • 一致性指事务操作不能破坏数据的一致性,数据库在一个事务的执行前后都应处于一致性状态。
      • 隔离性指数据库并发情况下,并发的事务直接是隔离的,一个事务的执行不能被其他事务影响。
      • 持久性指一旦事务提交,则其对数据的变更就是永久性的,即使数据库发生任何故障都不应该对数据造成任何影响。
    • 以下业务中,虽然执行了添加和删除用户的两个操作,但因为删除操作的失败,导致数据库中的数据与我们原本期望的不一致,因此违反了 ACID 原则,Spring 中有对事务的相关配置来避免此种情况的发生。

      • 业务代码

        • User.java

          @Data
          @AllArgsConstructor
          @NoArgsConstructor
          public class User {
              private int id;
              private String name;
              private String pw;
          }
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
        • UserMapper.java

          public interface UserMapper {
              public List<User> selectUser();
          
              public int addUser(User user);
          
              public int deleteUser(int id);
          }
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
        • UserMapper.xml

          
          DOCTYPE mapper
                  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
                  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
          <mapper namespace="com.why.mapper.UserMapper">
          
              <insert id="addUser" parameterType="com.why.pojo.User">
                  insert into user (id, name, pw) values (#{id}, #{name}, #{pw});
              insert>
          
              
              <delete id="deleteUser" parameterType="int">
                  deletes from user where id = #{id};
              delete>
          
          mapper>
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
        • UserMapperImpl.java

          public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper {
          
              public List<User> selectUser() {
                  UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
          
                  User user = new User(5, "李四", "555555");
                  mapper.addUser(user);
                  mapper.deleteUser(5);
                  List<User> users = mapper.selectUser();
                  return  users;
              }
          
              public int addUser(User user) {
                  int i = getSqlSession().getMapper(UserMapper.class).addUser(user);
                  return i;
              }
          
              public int deleteUser(int id) {
                  int i = getSqlSession().getMapper(UserMapper.class).deleteUser(5);
                  return i;
              }
          }
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
        • MyTest.xml

          @Test
              public void testProblem() {
                  ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
                  UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
                  List<User> users = userMapper.selectUser();
                  for (User user : users) {
                      System.out.println(user);
                  }
          
              }
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
      • 执行结果

        • 控制台报删除语句的错误

          在这里插入图片描述

        • 数据库执行了添加,没有删除,导致数据不一致问题

          在这里插入图片描述

    13.1 Spring 事务管理

    • 声明式事务:AOP 的应用,不影响业务代码。

      • 在 Spring 的配置文件中创建一个 DataSourceTransactionManager 对象

        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            
            <property name="dataSource" ref="dataSource"/>
        bean>
        
        • 1
        • 2
        • 3
        • 4
      • 结合 AOP 实现事务的织入

        
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            
            
            <tx:attributes>
                <tx:method name="add" propagation="REQUIRED"/>
                <tx:method name="delete" propagation="REQUIRED"/>
                <tx:method name="update" propagation="REQUIRED"/>
                <tx:method name="query" read-only="true"/>
                <tx:method name="*" propagation="REQUIRED"/>
            tx:attributes>
        tx:advice>
        
        
            <aop:config>
                <aop:pointcut id="txPointcut" expression="execution(* com.why.mapper.*.*(..))"/>
                <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
            aop:config>
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
      • 控制台报错

        在这里插入图片描述

      • 数据库数据保持了一致性

      在这里插入图片描述

    • 编程式事务:在代码中进行事务的管理。

  • 相关阅读:
    C++ IO流
    华为防火墙基本原理工作方法总结
    接口自动化测试要做什么?一文3个步骤带你成功学会!
    职场人一起进阶吧(内附技术人进阶路径、Java开源项目完整推荐等)
    记录--h5调用手机摄像头踩坑
    零基础入门JavaWeb——正则表达式
    医院用故障电弧探测器AAFD 安科瑞 时丽花
    敞开心扉地说家人们,爬也要爬进互联网大厂
    设计模式学习笔记 - 开源实战四(中):剖析Spring框架中用来支持扩展的设计模式
    Unity ab包加载文本 puerts 自定义loader
  • 原文地址:https://blog.csdn.net/qq_42651415/article/details/133239345