• Spring事务



    一、概念

    • 事务作用:在数据层保障一系列的数据库操作同成功同失败
    • Spring事务作用:在数据层或业务层保障一系列的数据库操作同成功同失败

    Spring为了管理事务,提供了一个平台事务管理器PlatformTransactionManager

    数据库事务:
    事务是一组操作的执行单元,相当于数据库操作来讲,事务管理的是一组SQL指令,比如增加,修改,删除等。事务的一致性要求事务内的操作必须全部执行成功,如果在此过程中出现了差错,比如有一条SQL语句没有执行成功,那么一组数据操作都将全部回滚

    • 数据库四大特性
      • atomic(原子性):要么都发生,要么都不发生
      • consistent(一致性):数据应该不被破坏。
      • isolate(隔离性):用户间操作不相混淆
      • durable(持久性):永久保存,例如保存到数据库中

    二、Spring控制事务的方式

    spring控制事务是以bean组件的函数为单位的,如果一个函数正常执行完毕,该函数内的全部数据库操作按照一次事务提交,如果抛出异常,全部回滚

    • 事务的传播策略
      如果两个bean组件都由spring控制事务,且组件的函数之间存在调用关系,(即:bean1函数a调用了bean2函数b),spring提供了一组配置方式供开发者选择,这些配置方式称为:事务的传播策略。
    • 事务的传播行为
    传播行为意义
    REQUIRED业务方法需要在一个事务中运行。如果方法运行时,已经处在一个事务中,那么加入到该事务,否则为自己创建一个新的事务
    NOT_SUPPORTED声明方法不需要事务。如果方法没有关联到一个事务,容器不会为它开启事务。如果方法在一个事务中被调用,该事务会被挂起,在方法调用结束后,原先的事务便会恢复执行
    REQUIRES-_NEW属性表明不管是否存在事务,业务方法总会为自己发起一个新的事务。如果方法已经运行在一个事务中,则原有事务会被挂起,新的事务会被创建,直到方法执行结束,新事务才算结束,原先的事务才会恢复执行
    MANDATORY该属性指定业务方法只能在一个已经存在的事务中执行,业务方法不能发起自己的事务。如果业务方法在没有事务的环境下调用,容器就会抛出例外。

    三、案例

    • 1、定义dao接口
    public   interface UserDao {
    
              //name1:A同学     name2:B同学   A同学给B同学转帐100块:A同学-100 ;B同学+100
    
              void   transMoney(String name1,String name2,BigDecimal money);
    
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 2、编写dao接口的实现类
    @Repository
    
      public class UserDaoImpl implements   UserDao{
    
         
    
          @Autowired
    
              private   JdbcTemplate jdbcTemplate;
    
              @Override
    
              @Transactional(propagation   = Propagation.REQUIRED)
    
              public   void transMoney(String name1, String name2, BigDecimal money) {
    
                       
    
                        //B同学收到了100块
    
                        String   sql1="update user set sal=sal+? where uname=?";
    
                       
    
                        //A同学消失了100块
    
                        String   sql2="update set sal=sal-? where uname=?";
    
                       
    
                        jdbcTemplate.update(sql1,   new Object[] {money,name1});
    
                        jdbcTemplate.update(sql2,   new Object[] {money,name2});
    
                       
    
              }
    
     
    
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 3:编写数据库连接信息jdbc.properties文件
    DRIVER=com.mysql.jdbc.Driver
    
    URL=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf-8
    
    NAME=root
    
    PWD=root
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 4:Spring配置文件的修改
    
    
    <context:component-scan   base-package="com">context:component-scan>
    
    
    
    <aop:aspectj-autoproxy>aop:aspectj-autoproxy>
    
     
    
    
    
    
    
    <bean   class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    
          <property name="locations"   >
    
                              <list>
    
                                        <value>jdbc.propertiesvalue>
    
                              list>
    
          property>
    
    bean>
    
    
    
    <bean   id="dataSource"   class="com.mchange.v2.c3p0.ComboPooledDataSource">
    
          <property name="user"   value="${NAME}">property>
    
          <property name="password"   value="${PWD}">property>
    
          <property   name="driverClass" value="${DRIVER}">property>
    
          <property name="jdbcUrl"   value="${URL}">property>
    
    bean>
    
    
    
    <bean   id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"   autowire="byName">
    
          <constructor-arg index="0"   ref="dataSource">constructor-arg>
    
    bean>
    
     
    
      
    
    <bean   id="tx" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    
          <property   name="dataSource" ref="dataSource">property>
    
    bean>
    
     
    
    
    
      
    
    <tx:annotation-driven   transaction-manager="tx"/>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 5:编写测试类
    
    public static void main(String[] args) {
    
      ApplicationContext ctx = new   ClassPathXmlApplicationContext("spring-common4.xml");
    
      UserDao ud = (UserDao)   ctx.getBean("userDaoImpl");
    
      //转账
    
      ud.transMoney("张三", "李四",new BigDecimal(100));
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    学习笔记:SpringCloud 微服务技术栈_高级篇⑤_可靠消息服务
    微信小程序手机号快速验证组件调用方式
    基于Google Gemini 探索大语言模型在医学领域应用评估和前景
    基于Springboot搭建java项目(十六)——Kafka的简介
    Say Goodbye to OOM Crashes
    2023-2028年中国高纯氟化铵市场深度分析及发展规模预测报告
    Redis -- 秒杀
    阿里云有奖体验:用PolarDB-X搭建一个高可用系统
    WPF-UI布局
    谷粒学院——前台用户使用系统
  • 原文地址:https://blog.csdn.net/qq_54351538/article/details/127789925