0
点赞
收藏
分享

微信扫一扫

阿里云国际站香港地域服务器访问延迟丢包的原因及解决方法

追风骚年 2023-08-03 阅读 44

目录

一、什么是事务,为什么要用事务

二、Spring声明式事务

🍅 1、@Transactional的使用

🎈 事务回滚

🎈注意:异常被捕获,不会发生事务回滚

🍅 2、@Transactional 作⽤范围

🍅 3、@Transactional 参数说明 

🍅 4、@Transactional的工作原理

 三、事务的特性以及隔离级别(重要)

🍅 事务的特性(ACID)

🍅 Spring隔离级别

四、Spring事务的传播机制

🍅为什么需要事务传播机制

🍅 事务传播机制的种类

        🎈Propagation.REQUIRED:

        🎈 Propagation.SUPPORTS

         🎈 Propagation.NEVER

        🎈Propagation.NESTED


一、什么是事务,为什么要用事务

下面主要介绍声明式事务

二、Spring声明式事务

🍅 1、@Transactional的使用

🎈 事务回滚

 声明式事务的使用很简单,只需要在方法上添加@Transactional注解就可以实现了

代码示例:

@Data
public class UserInfo {
    private int id;
    private String username;
    private String password;
    private String photo;
    private LocalDateTime createtime;
    private LocalDateTime updatetime;
    private int state;
}
@Mapper
public interface UserMapper {
    @Insert("insert into userinfo(username,password) values (#{username},#{password})")
    int add(UserInfo userInfo);
}
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public int add(UserInfo userInfo){
        return userMapper.add(userInfo);
    }
}
@RequestMapping("/user")
@RestController
public class UserController {

    @Autowired
    private UserService userService;
    @RequestMapping("/add")
    @Transactional
    public int add(){
//        1.非空判断
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("huhu");
        userInfo.setPassword("123");
//        2.调用service执行添加
        int result = userService.add(userInfo);
        System.out.println("result:" + result);
        int num = 10/0;
//        3.将结果给前端
        return result;
    }
}

执行以上代码:结果如下,发生算数异常

 但是sql执行没有异常:

🎈注意:异常被捕获,不会发生事务回滚

问题:当自己把程序捕获以后,代表着事务不会发现程序发生了异常,在这种情况下,事务不会发生回滚。

  @RequestMapping("/add")
    @Transactional
    public int add(){
//        1.非空判断
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("huhu");
        userInfo.setPassword("123");
//        2.调用service执行添加
        int result = userService.add(userInfo);
        System.out.println("result:" + result);
        try{
            int num = 10/0;
        }catch (Exception e){

        }
//        3.将结果给前端
        return result;
    }


🍅 2、@Transactional 作⽤范围

@Transactional 可以用来修饰类或者方法(public)

  • 修饰方法时,只能应用到public方法上面,否则不生效
  • 修饰类时,表明该注解对该类的所有public方法都生效

🍅 3、@Transactional 参数说明 

一般情况下,以下参数都是默认的


🍅 4、@Transactional的工作原理

@Transactional是基于AOP实现的,AOP又是基于动态代理实现的。

如果目标对象实现了接口,默认情况下就会采用JDK的动态代理,如果目标对象没有实现接口,会使用CGLIB的动态代理。

@Transactional在开始执行业务之前,通过代理先开始事务,在执行成功之后再提交事务。如果中途遇见异常,则回滚事务。

@Transactional实现思路预览:

@Transactional具体执行细节如下图所示:

 


 三、事务的特性以及隔离级别(重要)

🍅 事务的特性(ACID)

🍅 Spring隔离级别

默认情况下,是以SQL的事务隔离级别为主的(Isolation.DEFAULT)。

但是当Sping设置了事务隔离级别以后,就会以Spring的事务隔离级别为主。以下就是以SERIALIZABLE为主的。

 @RequestMapping("/add")
    @Transactional(isolation = Isolation.SERIALIZABLE)
    public int add(){
}

事务的隔离级别保证了多个并发事务执行的可控性。


四、Spring事务的传播机制

🍅为什么需要事务传播机制


🍅 事务传播机制的种类

         


        🎈Propagation.REQUIRED:

默认的事务传播级别,表示如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务

 示例:

UserService:

@Transactional
    public int add(UserInfo userInfo){
        int result = userMapper.add(userInfo);
        System.out.println("add result -> "+result);
        insert(userInfo);
        return result;
    }
    
    @Transactional
    public int insert(UserInfo userInfo){
        int result = userMapper.add(userInfo);
        System.out.println("insert resullt -> "+ result);
        int num = 10 / 0;
        return result;
    }

Controller:

@RequestMapping("/add")
    @Transactional(propagation = Propagation.REQUIRED)
    public int add(){
//        1.非空判断
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("万叶");
        userInfo.setPassword("123");
//        2.调用service执行添加
        int result = userService.add(userInfo);
        return result;
    }

此时结果是,报错是算数异常,进行了事务回滚,数据库中没有添加任何数据


        🎈 Propagation.SUPPORTS

如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行

示例:

UserService

@Transactional(propagation = Propagation.SUPPORTS)
    public int add(UserInfo userInfo){
        int result = userMapper.add(userInfo);
        System.out.println("add result -> "+result);
        insert(userInfo);
        return result;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    public int insert(UserInfo userInfo){
        int result = userMapper.add(userInfo);
        System.out.println("insert resullt -> "+ result);
        int num = 10 / 0;
        return result;
    }

 UserController:

@Transactional(propagation = Propagation.SUPPORTS)
    public int add(){
//        1.非空判断
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("万叶");
        userInfo.setPassword("123");
//        2.调用service执行添加
        int result = userService.add(userInfo);
        return result;
    }

当前调用链不存在事务,结果是数据库中添加了两条数据,并且报错是算数异常,但是并没有进行数据回滚


         🎈 Propagation.NEVER

以非事务方式运行,如果当前存在事务,则抛出异常

 UserController:

 @RequestMapping("/add")
//调用链存在事务
    @Transactional(propagation = Propagation.REQUIRED)
    public int add(){
//        1.非空判断
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("万叶");
        userInfo.setPassword("123");
//        2.调用service执行添加
        int result = userService.add(userInfo);
        return result;
    }

 USerService:

@Transactional(propagation = Propagation.NEVER)
    public int add(UserInfo userInfo){
        int result = userMapper.add(userInfo);
        System.out.println("add result -> "+result);
        insert(userInfo);
        return result;
    }

    @Transactional(propagation = Propagation.NEVER)
    public int insert(UserInfo userInfo){
        int result = userMapper.add(userInfo);
        System.out.println("insert resullt -> "+ result);
        int num = 10 / 0;
        return result;
    }

 说明程序在发现有事务以后,就没有运行了,不存在事务回滚,而是发现事务以后,程序就没有运行,而是直接抛出异常。


        🎈Propagation.NESTED

如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于Propagation.REQUIRED

 示例:

UserService:

@Transactional(propagation = Propagation.NESTED)
    public int add(UserInfo userInfo){
        int result = userMapper.add(userInfo);
        System.out.println("add result -> "+result);
        return result;

    }

    @Transactional(propagation = Propagation.NESTED)
    public int insert(UserInfo userInfo){
        int result = userMapper.add(userInfo);
        System.out.println("insert resullt -> "+ result);

        try{
            int num = 10 / 0;
        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return result;
    }

UserController:

@RequestMapping("/add")
    @Transactional(propagation = Propagation.REQUIRED)
    public int add(){
//        1.非空判断
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("影");
        userInfo.setPassword("123");
//        2.调用service执行添加
        int result = userService.add(userInfo);
        userService.insert(userInfo);
        return result;
    }

结果如下:

举报

相关推荐

0 条评论