spring事务传播机制之《REQUIRED》
spring事务传播指一个service方法调用多个其他service的方法时事务的范围。即各个被调用的方法和调用者之间怎样处理数据库事务。
spring中共有七中事务类型:REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW、NOT_SUPPORTED、NEVER、NESTED
本文将举例说明REQUIRED传播类型。
REQUIRED:如果当前(上层调用者方法)没有事务,则自己新建一个事务,如果当前(上层调用者方法)存在事务,则加入这个事务。spring默认使用该传播类型。
示例一:
// serviceA
@Transactional(propagation = Propagation.REQUIRED)
public void insertA() {
mapperA.insert()
}
// serviceB
@Transactional(propagation = Propagation.REQUIRED)
public void insertB() {
mapperB.insert();
throw new RuntimeException("抛出异常") // 此处抛出异常类型需为RuntimeException(运行时异常)或子类才会实现事务的回滚,Exception并不会回滚
}
// serviceC
@Transactional(propagation = Propagation.REQUIRED)
public void insertC() {
mapperC.insert();
}
public void test() {
this.insertC(); // 此处并不会开启事务,spring事务最终使用的是AOP实现,这里this为serviceC对象,并不会被代理,所以@Transactional不会生效
serviceA.insertA(); // 开启事务A
serviceB.insertB(); // 开启事务B
}
在该示例中由于调用者方法中没有事务,所以serviceA.insertA()开启了事务A,serviceB.insertB()开启了事务B,
两个方法分别在两个事务中执行,A添加成功,B被回滚。
示例二
// serviceA
@Transactional(propagation = Propagation.REQUIRED)
public void insertA() {
mapperA.insert()
}
// serviceB
@Transactional(propagation = Propagation.REQUIRED)
public void insertB() {
mapperB.insert()
throw new RuntimeException("抛出异常")
}
// serviceC
@Transactional(propagation = Propagation.REQUIRED)
public void insertC() {
mapperC.insert()
}
@Transactional(propagation = Propagation.REQUIRED)
public void test() { // 开启事务A
serviceA.insertA() // 加入事务A
serviceB.insertB() // 加入事务A
}
在该示例中调用者方法开启了事务A,由于上层方法存在事务,所以serviceA.insertA()和serviceB.insertB()方法都加入了事务A,两个方法都被回滚。
示例三
// serviceA
public void insertA() {
mapperA.insert()
}
// serviceB
@Transactional(propagation = Propagation.REQUIRED)
public void insertB() {
mapperB.insert()
throw new RuntimeException("抛出异常")
}
// serviceC
@Transactional(propagation = Propagation.REQUIRED)
public void insertC() {
mapperC.insert()
}
public void test() {
serviceA.insertA() // 没有事务
serviceB.insertB() // 开启事务A
}
在该示例中,调用者方法没有事务,serviceA.insertA()不开事务执行,serviceB.insertB()开启事务A执行,结果A添加成功,B被回滚。
示例四
// serviceA
@Transactional(propagation = Propagation.REQUIRED)
public void insertA() {
mapperA.insert();
}
// serviceB
@Transactional(propagation = Propagation.REQUIRED)
public B insertB() {
return mapperB.insert(B);
}
public void selectB(B) {
mapperB.insert(B);
}
// serviceC
@Transactional(propagation = Propagation.REQUIRED)
public void insertC() {
mapperC.insert(C);
}
@Transactional(propagation = Propagation.REQUIRED)
public void test1() { // 开启事务A
serviceA.insertA() // 加入事务A
B b serviceB.insertB() // 加入事务A
serviceB.selectB(b) // 查询到serviceB.insertB()添加的数据,因为查询和添加在一个事务中
}
public void test2() {
serviceA.insertA() // 开启事务A
B b = serviceB.insertB() // 开启事务B
serviceB.selectB(b) // 查询不到serviceB.insertB()添加的数据,因为serviceB.insertB()添加操作和查询并不在一个事务中。
}