@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项目中常见问题及解决方法,也可以继续关注本站来进行了解和学习。
推荐阅读: