Transactional的propagation属性区别
- REQUIRED:默认,只会有一个事务,无则创建,有则使用
- REQUIRES_NEW:每次都创建一个事务
- NESTED:在当前事务内嵌事务
需要注意的是,两个方法必须在两个不同的类中,不然回滚机制会有影响
假定有serviceB中有个方法B,包含jdbc操作,serviceA中有个方法A,包含jdbc操作,同时调用serviceB的方法B
REQUIRED:只会有一个事务,无则创建,有则使用
- testB有异常,testA捕获了异常,则testB回滚,testA不会滚,如果testA没捕获,则testA也回滚
@Transactional
@Override
public Result testA() {
testMapper.insert(new Test(UUId.getUUId())); // 因为testB有异常,不管对testB是否有try/catch,testA都会被回滚
try {
testService.testB();
} catch (RuntimeException e) {
e.printStackTrace();
}
return MyResult.success();
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public int testB() {
testMapper.insert(new Test(UUId.getUUId())); // 此操作会回滚
throw new RuntimeException();
}
- testA有异常,testB无异常,A和B会一起回滚
@Transactional
@Override
public Result testA() {
testMapper.insert(new Test("testA")); // 此操作由于该方法有异常会回滚
testService.testB();
throw new RuntimeException();
}
@Transactional(propagation = Propagation.REQUIRED)
@Override
public int testB() {
return testMapper.insert(new Test("testB")); // 此操作由于testA有异常则也会回滚
}
REQUIRES_NEW:每次都创建一个事务
- testB有异常,testA捕获了异常,则testB回滚,testA不会滚,如果testA没捕获,则testA也回滚
@Transactional
@Override
public Result testA() {
testMapper.insert(new Test(UUId.getUUId())); // 此操作会成功插入数据库,因为此方法没有异常,已捕获,如果没有捕获,那么此操作也会被回滚
try {
testService.testB();
} catch (RuntimeException e) {
e.printStackTrace();
}
return MyResult.success();
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Override
public int testB() {
testMapper.insert(new Test(UUId.getUUId())); // 此操作会回滚
throw new RuntimeException();
}
- testA有异常,testB无异常,A和B会一起回滚
@Transactional
@Override
public Result testA() {
testMapper.insert(new Test("testA")); // 此操作由于该方法有异常会回滚
testService.testB();
throw new RuntimeException();
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Override
public int testB() {
return testMapper.insert(new Test("testB")); // 此操作会成功插入数据库
}
NESTED:在当前事务内嵌事务
- testB有异常,testA捕获了异常,则testB回滚,testA不会滚,如果testA没捕获,则testA也回滚
@Transactional
@Override
public Result testA() {
testMapper.insert(new Test(UUId.getUUId())); // 此操作会成功插入数据库,因为此方法没有异常,已捕获,如果没有捕获,那么此操作也会被回滚
try {
testService.testB();
} catch (RuntimeException e) {
e.printStackTrace();
}
return MyResult.success();
}
@Transactional(propagation = Propagation.NESTED)
@Override
public int testB() {
testMapper.insert(new Test(UUId.getUUId())); // 此操作会回滚
throw new RuntimeException();
}
- testA有异常,testB无异常,A和B会一起回滚
@Transactional
@Override
public Result testA() {
testMapper.insert(new Test("testA")); // 此操作由于该方法有异常会回滚
testService.testB();
throw new RuntimeException();
}
@Transactional(propagation = Propagation.NESTED)
@Override
public int testB() {
return testMapper.insert(new Test("testB")); // 此操作由于testA有异常则也会回滚
}
宁静致远!