在springboot中使用事务(Transactional )

149 阅读4分钟

这是我的第一篇文章,创作时间: 2020年10月11日。
如有哪里写的不对的或者不合适以及不周到的地方,还请大佬们进行指正。

首先啊,我想先说明一下,本篇文章只是个人思想的记录和分享,没有实质代码的东西,如有需要了解相关编码教程的请到别人家再看看。

开始啦~ 进入正题。

       我们在大学或者其他学习过程中,最初接触到“事务”这个名词是在MySQL 中(反正我印象是~)。在MySQL 中,事务是这样定义的,要么全部执行,要么全部不执行。同时,事务也有四个特性,原子性,一致性,隔离性,持久性。包括还有事务的隔离级别(脏读,幻读,不可重复读等)具体啥含义自行百度。(菜鸟教程MySQL事务链接

       那么事务是用在什么地方了呢?教材上举的例子就是关于银行的例子。相信大家都已经耳熟能详。因为涉及到钱嘛,就是说,存钱,取钱或转账,无论哪个环节出现问题都需要“回滚”,来保证数据的一致性和正确性。其实,事务用处就是通过使用回滚来保证数据的一致性和正确性。

        好~! 事务介绍差不多了。还不明白事务的,可以再去百度百度。那么在MySQL 中使用事务如何编码呢?

1.begin开始一个事务
2.roolback 回滚一个事务
3.commit 提交一个事务

当然,在roolback 中要有一定的触发条件,比如插入不成功,需要回滚整个事务等等。

        这种就是编码式声明的事务。那么当我们在spring 中进行编程中,持久层进行对数据库的相关操作。那么事务也写在SQL 中或者业务逻辑代码中吗? 这种写法是不是会很繁琐,同时是不是会影响业务的代码。所以这种写法在实际编程过程中是很少用到的。因此就诞生了声明式事务。

事务的分类: 

 编程式事务: 通过编码的方式实现事务。一般情况下用的很少。因为它会影响业务的代码。

 _声明式事务_: 通过声明式的方式实现事务。用的很多,因为它是和业务代码耦合的,不会影响业务的代码。声明式事务,一般情况下分为两种,一种是XML 配置文件的形式进行声明事务,另一种是基于@Transactional 来声明事务。本文介绍通过注解的这种,因为简单高效嘛~~

在springboot 中的使用方法:

1.在XML中或者通过注解方式进行注入DataSourceTransactionManager。(具体怎么写再百度。)

2.使用**@Transactional** 进行事务的声明。@Transactional可以作用类和方法上。当作用于类上,该类的所有public 方法都配置相同的事务属性信息。 作用于方法上则表示该方法配置了事务属性信息。(注意:@Transactional 只能作用于public 类型的方法上面)

具体小例子:

@Service
public class xxxService{
    @Autowired    private xxxDao xxxDao;
    public void insert(){
        saveXXX();
    }
    @Transactional(rollbackFor = Throwable.class)    public void saveXXX(){
         xxxDao.delete();
         if (xxxDao.insert() != 1) throw new RuntimeException("数据插入失败");
    }
}

说明:

1.@Transactional 作用于方法表示该方法配置了事务,同时它有很多属性,如下:

属性名
说明
name
当在配置文件中有多个 TransactionManager , 可以用该属性指定选择哪个事务管理器。
propagation
事务的传播行为,默认值为 REQUIRED。
isolation
事务的隔离度,默认值采用 DEFAULT。
timeout
事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完成,则自动回滚事务。
read-only
指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。
rollback-for
用于指定能够触发事务回滚的异常类型,如果有多个异常类型需要指定,各类型之间可以通过逗号分隔。
no-rollback- for
抛出 no-rollback-for 指定的异常类型,不回滚事务。

2. 事务发生的条件:本例是Throwable。那么它的子类(Error 或 Exception) 触发时就会发生事务。RuntimeException 是 Throwable 的子类嘛。因为使用 tk.mybatis 中,insert 成功的默认值是 1嘛。所以当插入不成功够,则会抛出异常,这时候就会回滚。

注意:实际编码过程中,函数调用不会这么简单,一般情况。外层方法包含@Transactional ,内部调用方法发生异常会回滚;同理,内层方法进行@Transactional,不会影响外层方法。

若同一类中的其他没有@Transactional 注解的方法内部调用有@Transactional 注解的方法,有@Transactional 注解的方法的事务被忽略,不会发生回滚。
默认情况下,如果在事务中抛出了未检查异常(继承自 RuntimeException 的异常)或者 Error,则 Spring 将回滚事务;除此之外,Spring 不会回滚事务。

如有哪里不对的地方,还请各位大佬评论指正。抱拳了奥力给!!!