事物总共有7种 使用代码讲解比价容易理解
@Override
public void saveOk() {
Stu stu = new Stu();
stu.setName("ok");
stu.setAge(10);
saveStu(stu);
}
@Override
public void saveError() {
Stu stu = new Stu();
stu.setName("error-1");
stu.setAge(11);
saveStu(stu);
int a = 1/0;
Stu stu1 = new Stu();
stu1.setName("error-2");
stu1.setAge(22);
saveStu(stu1);
}
@Override
public void testTransactional() {
stuService.saveOk();
stuService.saveError();
}
- REQUIRED 默认
什么都不加:插入name为error-1和ok的两条数据
在testTransactional上加@Transactional(propagation = Propagation.REQUIRED):不会插入数据
在saveError上加@Transactional(propagation = Propagation.REQUIRED):插入name为ok的一条数据
在testTransactional和saveError上都加@Transactional(propagation = Propagation.REQUIRED):不会插入数据
- SUPPORTS
如果当前有事务,使用事物。当前没事务,不使用事物。
- MANDATORY
调用者必须拥有事物。
testTransactional 不加事务 saveError加 @Transactional(propagation = Propagation.MANDATORY) 会抛下面的异常。
org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'
在testTransactional上面加上事务即可
- REQUIRES_NEW
如果当前有事务则挂起该事务,并创建新事物。如果当前没有事物同REQUIRED
按照上面的代码在saveError上加上Propagation.REQUIRES_NEW,在testTransactional加上Propagation.REQUIRED不会在数据库产生数据
按照下面代码会插入name为error-1,error-2两条数据,额外新建一个事务 导致子方法内部不会回滚。
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Override
public void saveError() {
Stu stu = new Stu();
stu.setName("error-1");
stu.setAge(11);
saveStu(stu);
Stu stu1 = new Stu();
stu1.setName("error-2");
stu1.setAge(22);
saveStu(stu1);
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void testTransactional() {
stuService.saveOk();
stuService.saveError();
int a = 1/0;
}
- NOT_SUPPORTED
如果当前有事务则挂起,不使用事务。
按照下面的方法:会插入一条name为error-1的数据,saveOk()回滚而saveError不使用事物所以不回滚
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void testTransactional() {
stuService.saveOk();
stuService.saveError();
}
@Transactional(propagation = Propagation.NOT_SUPPORTED)
@Override
public void saveError() {
Stu stu = new Stu();
stu.setName("error-1");
stu.setAge(11);
saveStu(stu);
int a = 1/0;
Stu stu1 = new Stu();
stu1.setName("error-2");
stu1.setAge(22);
saveStu(stu1);
}
- NEVER
不使用事务,如果调用方存在事务,抛出异常。
- NESTED
如果当前存在事务,则创建一个子事务,否则同REQUIRED
按照下面代码不会在数据库里面产生数据,看上去和子方法上加REQUIRED效果一样,但是REQUIRED是并列的而NESTED是嵌套处理的。
主事务回滚子事务会一起回滚,子事务发生异常回滚,主事务可以选择是否回滚(通过try catch捕获)
@Transactional(propagation = Propagation.NESTED)
@Override
public void saveError() {
Stu stu = new Stu();
stu.setName("error-1");
stu.setAge(11);
saveStu(stu);
Stu stu1 = new Stu();
stu1.setName("error-2");
stu1.setAge(22);
saveStu(stu1);
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public void testTransactional() {
stuService.saveOk();
stuService.saveError();
int a = 1/0;
}
最后注意一点:Spring同一个类中的方法调用,则不会被方法拦截器拦截到,因此事务不会起作用