Spring基础学习之声明式事务

Spring基础学习之声明式事务,第1张

Spring基础学习之声明式事务

前言:

小伙伴们,大家好,我是狂奔の蜗牛rz,当然你们可以叫我蜗牛君,我是一个学习Java半年多时间的小菜鸟,同时还有一个伟大的梦想,那就是有朝一日,成为一个优秀的Java架构师。
这个Spring基础学习系列是用来记录我学习Spring框架基础知识的全过程 (这个系列是参照B站狂神的Spring5最新教程来写的,由于是之前整理的,但当时没有发布出来,所以有些地方可能有错误,希望大家能够及时指正!)
之后我将会以一天一更的速度更新这个系列,还没有学习Spring5框架的小伙伴可以参照我的博客学习一下;当然学习过的小伙伴,也可以顺便跟我一起复习一下基础。
最后,希望能够和大家一同进步吧!加油吧!少年们!
废话不多说,让我们开始今天的学习内容吧,今天我们来到了Spring基础学习的第十三站:声明式事务!

13.声明式事务 13.1 回顾事务 13.1.1 事务注意要点
  • 把一组业务当成一个业务来做:要么都成功,要么都失败!
  • 事务在项目开发中,十分的重要,涉及到数据的一致性问题,不能马虎!
  • 确保数据的完整性和一致性
13.1.2 事务ACID原则
  • 原子性要么都成功,要么都失败

  • 一致性事务提交前后的数据要保持一致,资源和状态不能改变,即最终一致性;其实还是要么都成功,要么都失败

  • 隔离性多个业务 *** 作同一个资源,防止数据损坏,即事务之间要隔离

  • 持久性事务一旦提交,无论系统发生什么问题,结果都不会被影响,被持久化的写到存储器中

13.2 声明式事务的使用 13.2.1 编写实体类、接口和接口实现类 1.编写User实体类
package com.kuang.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data // 引入无参构造,get和set方法以及toString方法
@AllArgsConstructor // 引入有参构造
@NoArgsConstructor // 再次引入无参构造,防止引入有参构造时覆盖无参构造
public class User {
    
    private int id;
    private String name;
    private String pwd;
}
2.编写UserMapper接口
package com.kuang.mapper;

import com.kuang.pojo.User;
import java.util.List;

public interface UserMapper {
    
    //获取所有用户信息
    public List getUsers();
    
    //增加一个用户
     public int insertUser(User user);
    
    //删除一个用户
     public int deleteUser(int id);

}
3.编写UserMapper.xml配置文件 3-1 SQL语句正确编写




    
    
    
    
        Select * from mybatis.user
    
    
    
    
        Insert into mybatis.user(id, name, pwd)
        values(#{id} ,#{name}, #{pwd})
    
    
    
    
        
        Delete * from mybatis.user where id = #{id}
    
    

4.编写UserMapperImpl2接口实现类
package com.kuang.mapper;

import com.kuang.pojo.User;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import java.util.List;

// 继承SqlSessionDaoSupport对象并且实现UserMapper接口
public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper{
    
    // 查询所有的用户信息
    public List getUsers() {
        User user = new User(4,"钟兴民","zxm123456");
        // 获取sqlSession对象,获取Mapper接口对象
        UserMapper userMapper = getSqlSession().getMapper(UserMapper.class);
        userMapper.insertUser(user);
        userMapper.deleteUser(3);
        // 调用接口的getUsers方法
        return userMapper.getUsers();
    }
    
    // 增加用户信息
    public int insertUser(User user) {
        return getSqlSession().getMapper(UserMapper.class).insertUser(user);
    }
    
    // 通过id删除用户信息
    public int deleteUser(int id) {
        return getSqlSession().getMapper(UserMapper.class).deleteUser(id);
    }
    
}
13.2.2 编写核心配置文件 1.编写mybatis的核心配置文件




    
    
    
        
    

    
    
        
    


2.编写spring的dao配置文件和spring的主配置文件 2-1 编写spring-dao.xml配置文件
  • 引入配置文件约束


    
    
  • 配置DataSource数据源


    
    
        
        
        
        
        
        
        
    

  • 注入sqlSessionFactory工厂对象

    
    
    
    
    
    
    
    
    
    

  • 注入sqlSessionTemplate对象

    
    
    
    

2-2 编写applicationContext.xml主配置文件



    
    
    
    
    
        
    
    
    
    
        
    


3.修改spring-dao.xml配置文件 3-1导入spring-tx约束
  • 在beans标签中加入以下的spring-tx约束
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
  • 加入spring-tx约束后如下




3-2 配置声明式事务
  • 注入DataSourceTransactionManager数据源事务管理器


    

3-3 结合AOP实现事务的织入


    
    
    
        
        
        
        
        
        
        
        
        
        
        
        
    

Propagation类表示对这些方法怎样使用事务,使用还是不用

Propagation类有七种事务配置属性,默认是REQUIRED

  • REQUIRED支持当前事务,如果当前没有事务,就新建一个事务,则是常见的选择
  • SUPPORTS支持当前事务,如果当前没有事务,就以非实物方式执行
  • MANDATORY支持当前事务,如果当前没有事务,就抛出异常
  • REQUIRED_NEW新建事务,如果当前存在事务,把当前事务挂起
  • NO_SUPPORTED以非事务方式执行 *** 作,如果当前存在事务,就把当前事务挂起
  • NEVER以非事务方式执行,如果当前存在事务,则抛出异常
  • NESTED支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务
3-4 配置业务切入

    
    
    
    
    

  • pointcut切入点,切面通知执行的“地点”
  • expression定义切入点表达式,execution(* com.kuang.mapper….(…))
  • execution()表达式主体
  • 第一个 * 号表示返回类型,*号表示所有的类型
  • com.kuang.mapper…表示要拦截的包名,后面的两个.号表示当前包和当前包的所有子包
  • 第二个 * 号表示类名,*号表示所有的类
  • * ( … )最后这个*号表示方法名,*号表示所有的方法,后面的()表示方法的参数,两个.号表示任何参数
13.2.3 编写MyTest测试类
package com.kuang.dao;

public class MyTest { 
    
		// 获取所有的用户信息:使用继承SqlSessionDaoSupport方式
        @Test
        public void getUsers3()  {
            // 获取上下文信息,得到Spring的IOC容器
            ApplicationContext context= new ClassPathXmlApplicationContext("applicationContext.xml");
            // 从IOC容器中获取UserMapper的Bean信息(说明类型后就不需要强制转换了)
            UserMapper userMapper = context.getBean("userMapper2",UserMapper.class);
            // 调用getUsers获取所有用户,然后进行遍历
            for (User user : userMapper.getUsers()) {
                System.out.println(user);
            }
       }
    
}
13.2.4 测试结果 1.未配置声明式事务且SQL语句编写错误
  • 查看控制台输出

  • 查看数据库信息

结果:报错,删除用户的SQL语句出错,删除id为3的用户失败,但是id为4的用户仍然插入成功了

分析:

这两组事务同时执行,删除用户的事务失败了,但插入用户的事务却执行成功了,这显然不符合事务的ACDI原则:即要么都成功,要么都失败!

2.配置声明式事务后且SQL语句编写正确
  • 查看控制台输出

  • 查看数据库信息

结果:增加id为4用户,删除id为6的用户成功!两组事务共同执行,都执行成功了!

好了,今天的有关声明式事务的学习就到此结束啦,欢迎小伙伴们积极学习和讨论,喜欢的可以给蜗牛君点个关注,顺便来个一键三连,我们下期见,拜拜啦!


参考视频链接:https://www.bilibili.com/video/BV1WE411d7Dv(【狂神说Java】Spring5最新教程IDEA版通俗易懂)

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/4658448.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-11-06
下一篇2022-11-06

发表评论

登录后才能评论

评论列表(0条)

    保存