Spring事务和事务传播机制

发布于:2025-05-02 ⋅ 阅读:(17) ⋅ 点赞:(0)

1.什么是事务

1.事务:事务是一组操作的集合,事务让我们的一组操作只能全部成功或者全部失败,不能存在只成功一半的情况。

2.事务的操作:

(1)开启事start transaction/ begin (⼀组操作前开启事务)
(2)   提交事务: commit (这组操作全部成功, 提交事务)
(3)回滚事务: rollback (这组操作中间任何⼀个操作出现异常, 回滚事务

2.Spring中事务的实现

1.Spring编程式事务

springboot内置了两个对象:

1.DataSourceTransactionManager事务管理器,用来获取事务(开启事务),提交或回滚事务

2 . TransactionDefinition 是事务的属性, 在获取事务的时候需要将
TransactionDefinition 传递进去从⽽获得⼀个事务 TransactionStatus
@RestController
@RequestMapping("/user")
public class TController {

    @Autowired
    private UserService userService;

    @Autowired
    //事务管理器
    private DataSourceTransactionManager dataSourceTransactionManager;


    @Autowired
    //事务定义
    private TransactionDefinition transactionDefinition;

    @RequestMapping("/registerUser")
    public String insertUser(String userName,String password) {
        //开启事务
        TransactionStatus transactionStatus=dataSourceTransactionManager.getTransaction(transactionDefinition);
        //执行SQL
        userService.insertUser(userName,password);
        //提交事务
        //dataSourceTransactionManager.commit(transactionStatus);
        //回滚事务
        dataSourceTransactionManager.rollback(transactionStatus);
        return "注册成功";
    }
}

2.Spring声明式事务

引入依赖:

<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-tx</artifactId>
</dependency>

在需要执行的事务的方法上添加@Transactional注解,执行的时候如果发生异常就会自动回滚。

@RestController
@RequestMapping("/trans")
public class TransController {
    @Autowired
    private UserService userService;


    @RequestMapping("/registerUser")
    @Transactional
    public String insertUser(String userName,String password) {

        //执行SQL
        userService.insertUser(userName,password);
        //此处发生异常就会自动回滚
        int a=10/0;

        return "注册成功";
    }

}

@Transactional作用

@Transactional可以修饰方法或类

修饰方法时:只有修饰public方法时才会生效(修饰其他方法时不会报错,也不会生效)

修饰类时:对@transactional修饰的类中所有public方法都生效

在执行方法的过程中出现异常,且异常未被捕获,就会进行事务回滚操作,但若是事务被捕获,就会认为是成功执行,依然会提交事务。

手动回滚事务

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly手动回滚事务

@RequestMapping("/registerUser1")
    @Transactional
    public String insertUser1(String userName,String password) {

        //执行SQL
        userService.insertUser(userName,password);
        //此处发生异常就会自动回滚
        try {
            int a=10/0;
        } catch (Exception e) {
            //手动回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }

        return "注册成功";
    }

3.@Transactional三个常见属性

1.rollback:异常回滚,指定能够触发事务回滚的异常属性,可以指定多个异常类型。

@Transactional默认只有error或者RuntimeException以下级别的异常才会发生回滚。

@RequestMapping("/registerUser2")
    @Transactional(rollbackFor = {Exception.class})
    public String insertUser2(String userName,String password) throws IOException {

        //执行SQL
        userService.insertUser(userName,password);
        //此处发生异常就会自动回滚
        if(true) {
            throw new IOException();
        }

        return "注册成功";
    }

2.lsolation:事务的隔离级别,默认值为Isolation.DEFAULT(连接的数据库的隔离级别)。

Spring事务隔离级别有5种:

(1)Isolation.DEFAULT:以连接数据库的事务隔离级别为主。

(2)Isolation.READ_UNCOMMITTED:读未提交,对应SQL标准中READ UNCOMMITTED

(3)Isolation.READ_COMMITTED读已提交,对应SAL标准中READ COMMITTED

  (4)Isolation.REPEATABLE_READ可重复读,对应SQL标准中REPEATABLE READ

  (5)Isolation.SERIALIZABLE:串行化,对应SQL标准中SERIALIZABLE

@RequestMapping("/registerUser3")
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public String insertUser3(String userName,String password) throws IOException {

        //执行SQL
        userService.insertUser(userName,password);
        //此处发生异常就会自动回滚
        if(true) {
            throw new IOException();
        }

        return "注册成功";
    }

3.propagation:事务的传播机制,默认为Propagation.REQUIRED

多个方法存在相互调用的关系,事务是如何在这些方法中进行传播的。

@Transactional 注解⽀持事务传播机制的设置, 通过 propagation 属性来指定传播⾏为.
Spring 事务传播机制有以下 7 种:
1. Propagation.REQUIRED : 默认的事务传播级别. 如果当前存在事务, 则加⼊该事务. 如果当前没
有事务, 则创建⼀个新的事务.
2. Propagation.SUPPORTS : 如果当前存在事务, 则加⼊该事务. 如果当前没有事务, 则以⾮事务的
⽅式继续运⾏.
3. Propagation.MANDATORY :强制性. 如果当前存在事务, 则加⼊该事务. 如果当前没有事务, 则
抛出异常.
4. Propagation.REQUIRES_NEW : 创建⼀个新的事务. 如果当前存在事务, 则把当前事务挂起. 也
就是说不管外部⽅法是否开启事务, Propagation.REQUIRES_NEW 修饰的内部⽅法都会新开
启⾃⼰的事务, 且开启的事务相互独⽴, 互不⼲扰.
5. Propagation.NOT_SUPPORTED : 以⾮事务⽅式运⾏, 如果当前存在事务, 则把当前事务挂起(不
⽤).
6. Propagation.NEVER : 以⾮事务⽅式运⾏, 如果当前存在事务, 则抛出异常.
7. Propagation.NESTED : 如果当前存在事务, 则创建⼀个事务作为当前事务的嵌套事务(如果子方法对异常进行了处理就会全部回滚)来运⾏. 如果当前没有事务, 则该取值等价于 PROPAGATION_REQUIRED

网站公告

今日签到

点亮在社区的每一天
去签到