@transactional注解的作用是什么?作用详解

@Transactional是spring当中经常被使用到的注解,那么对于@transactional它的作用你都了解吗?有什么用呢?

在一般的情况之下,需要对一个service方法添加事务的时候,加上@transactional注解,假如,发生了unchecked exception,那么,就会发生rollback。

下面是一个比较典型的例子:

@Service
public class StudentService
{
    @Autowired
    StudentDao studentDao;
    @Transactional
    public void innerSave(int i)
    {
        Student student = new Student();
        student.setName("test" + i);
        studentDao.save(student);
        //i=5 会出现异常
        int a = 1 / (i - 5);
    }
}

在调用innerSave(5)的时候,会发生运算异常,导致保存操作回滚。

新需求:

循环保存10个学生,发生异常的时候要求回滚。

有了如下的代码。

在StudentService.java添加下面的方法:

public void outerLooper1()
{
    for (int i = 1; i <= 10; i++)
    {
        try
        {
            innerSave(i);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

考虑:test5这个学生是否保存了呢?

结果:依旧出现了,那么再考虑:问题的出处。

其实,这也是很好理解的,spring当中@Transactional的事务开启是依托于接口,又或者是类的代理被创建的,所以的话,在同一个类中一个普通方法outerLooper1()调用另一个有事务的方法innerSave(),事务不会起作用,想要解决这个问题的话,通常,很多人的做法都是写一个帮助类,注入到当前类中,来完成事务操作。

@Autowired
UtilService utilService;
public void outerLooper2()
{
    for (int i = 1; i <= 10; i++)
    {
        utilService.innerSave(i);
    }
}

在spring中使用事务的时候,一定要注意遵守一些规范和了解一些容易出问题的地方:

在需要事务管理的地方加@Transactional 注解;

@Transactional注解能够被应用于接口定义和接口方法、类定义和类的public方法上;

Transactional注解只能够应用到public可见度的方法上。

假如,在protected、private或者package-visible的方法上使用@Transactional 注解,它不会报错,可是,这个被注解的方法将不会展示已配置的事务设置。

Spring团队建议在具体的类(或类的方法)上使用 @Transactional 注解,而不要使用在类所要实现的任何接口上。

在接口上使用@Transactional注解,只能当你设置了基于接口的代理时它才生效。

这主要是因为,注解是不能继承的,那么,这也就表示着,假如,正在使用基于类的代理的时候,那么事务的设置将不可以被基于类的代理所识别,而且对象也不会被事务代理所包装。

@Transactional的事务开启是基于接口的或者是基于类的代理被创建。

所以在同一个类中一个方法调用另一个方法有事务的方法,事务是不会起作用的。

了解事务的隔离级别-各个数据库默认的隔离级别是不一样的,在spring中用的是isolation = Isolation.READ_COMMITTED来设置;

了解事务的传播机制-当发生事务嵌套的时候,按照业务选择对应的传播机制,用propagation=Propagation.REQUIRED来设置。

对于@transactional你还有什么想要了解的吗?请继续关注奇Q工具网的java架构师栏目的内容来了解吧。

除此之外,假如你还想了解更多的java基础知识,以及和java项目中常见问题及解决方法,也可以继续关注本站来进行了解和学习。

推荐阅读:

springboot注解大全,注解详解

spring注入方式,Spring三种注入方式实现

springboot读取配置文件有哪几种常见方式?要怎么实现?