Spring事务

在MySql中,我们就已经学习过事务了,想必对于事务的大致意思已经是很明确了,但是,在Spring中事务又是指的是什么呢??感兴趣的各位铁汁,请跟着小编的思路来看一下本文相关内容吧!

Spring中的事务操作分为两类:

  1. 编程式事务(手动写代码操作事务)《——》了解即可(操作繁琐)
  2. 声明式事务(利用注解,自动开启和提交事务)

前提提示:事务:将一组操作封装成一个执行单元(封装到一起)要么全部成功,要么全部失败!

创建Spring项目的时候,若与MySql相关,请选择框架:

  • lombok
  • Spring Boot Devtools
  • Spring Web
  • MyBatis Framework
  • MySQL Driver
  • Spring事务_第1张图片

Spring 声明式事务(自动):

声明式事务的实现很简单,只需要在需要的方法上添加@Transactional注解就可以实现了,无需手动开启事务和提交事务,进入方法时自动开始事务,方法执行完会自动提交事务(没有出现异常情况),如果中途发生了没有处理的异常会自动回滚事务。

那么,请看小编的下述代码:


@RestController
@RequestMapping("/user2")
public class UserController2 {

    @Autowired
    private UserServerice userServerice;

    @RequestMapping("/del")
    @Transactional
    //设置事务的各类级别 @Transactional(isolation = Isolation.DEFAULT)
    public int del(Integer id){
        if (id==null || id <= 0){
            return 0;
        }
        return userServerice.del(id);
    }
}
//    @Transactional在方法开始之前开启事务,方法正常执行接收之后,提交事务,如果执行途中发生异常,则回滚事务
@Transactional在方法开始之前开启事务,方法正常执行接收之后,提交事务,如果执行途中发生异常,则回滚事务

接下来,在本文中,我们将会接触到另一个方法:Test(测试)

Spring事务_第2张图片

小编一开始是录了视频,但是在本文中传输不过来(懒),然后就手动搞了个操作步骤!!嘿嘿


通过上述步骤,我们便生成了Test测试类,那么,便可以进行下一步操作了!


class UserController2Test {

    @Transaction
    public int del(Integer id){
        if (id==null || id <=0){
            return 0;
        }

        int result=userService.del(id);//先删除
        System.out.println("删除"+result);
        int num=10/0;//异常,且没有处理
        return result;
    }
}

扩展:

@Transactional注解与@Transaction注解
@Transactional注解的作用范围:
  • @Transactional可以用来修饰方法或类
  • 修饰方法时:需要注意,只能应用到public方法上,否则不生效(推荐此用法)
  • 修饰类时:表明该注解对该类中所有的public方法都生效
@Transaction参数说明
value 当配置了多个事务管理器时,可以使用该属性指定选择哪个事务管理器
TransactionManager
当配置了多个事务管理器时,可以使用该属性指定选择哪个事务管理器
propagation 事务的传播行为,默认Propagation.REQUIRED
isolation 事务的隔离级别,默认Isolation.DEFAULT
timeout 事务的起始时间,默认为-1,如果超过该时间限制,但事务还没有完成,则回滚事务
readOnly 指定事务是否为只读事务,默认为false,为列忽略哪些不需要事务的方法
rollbackFor 用于指定能够触发事务,回滚的异常类型,可以指定多个异常类型
rollbackForClassName 用于指定能够触发事务,回滚的异常类型,可以指定多个异常类型
noRollbackFor 抛出指定的异常类型,不回滚事务,也可以指定多个异常类型
noRollbackForClassName

 

抛出指定的异常类型,不回滚事务,也可以指定多个异常类型

Spring事务隔离级别:

DEFAULT 以连接的数据库隔离级别为准 脏读 不可重复读 幻读
READ_UNCOMMITTED 读未提交
READ_COMMITTED 读已提交 不可
REPEATABLE 可重复读 不可 不可
SERIALIZABLE 串行化 不可 不可 不可

事务隔离级别设定:

@Transactional(isolation = Isolation.DEFAULT)

设置事务隔离级别,在进行多线程并发访问的时候,会有隔离上的区别(发生在并发环境中的问题)

事务类型:

  1. 普通事务
  2. 只读事务:没有设置事务隔离级别的时候走可重复读(相比于无事务更可控——》可以自定义事务隔离级别)
  3. 无事务:(默认的隔离级别:可重复读——》不可自定义事务隔离级别)

声明式事务发生异常,并添加try-catch有可能出现异常,事务不会回滚,那么,就会导致业务执行出错。

    @Transactional
    @RequestMapping("/del")
    public int del(Integer id){
        if (id==null || id <=0){
            return 0;
        }

        int result=userService.del(id);//先删除
        System.out.println("删除"+result);
        //不会回滚
        try {   //有异常,但被捕获,此时非常危险
            int num=10/0;//异常
        }catch (Exception e){
            e.printStackTrace();//仅打印异常,不进行其他操作
        }
        return result;
        return 0;
    }

解决方法:

1.将异常抛出去,让框架感知到异常,如果框架感知到异常之后,它会自动回滚事务

        try {   
            int num=10/0;
        }catch (Exception e){
            e.printStackTrace();
        }
//将异常抛出,让框架去处理

2.通过代码的方式手动回滚事务(企业中常见)

     try {
            int num=10/0;
        }catch (Exception e){
            //异常处理:如:记录错误,提示报警信息…………
            //手动回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); //手动回滚事务
            //Transaction事务
            //Aspect切面
            //Support支持对象
            //currentTransactionStatus当前事务状态码
            //setRollbackOnly回滚
        }

经典面试题:Spring事务失效的场景有哪些??

  1. 非public修饰的方法
  2. timeout超时
  3. 代码中有try-catch《——》异常未处理
  4. 调用类内容使用@Transactional方法
    A方法调用B方法,但B方法虽然用public修饰,但由于使用了@Transaction导致事务失效(A方法未使用)
  5. 数据库不支持事务

@Transaction工作原理:

@Transaction是基于AOP实现的,AOP又是动态代理实现的,如果目标对象实现了接口,默认情况下会采用JDK的动态代理,如果目标对象没有实现接口,会采用CGLIB动态代理,@Transaction在开始执行业务之前,通过代理先开启事务,在执行成功之后在提交事务,如果中途遇到了异常,则回滚事务。

你可能感兴趣的:(操作系统哪些事?,java要笑着学,spring,java,后端)