前提
在需要添加事务的地方,添加@Transactional注解,否则事务无法生效,并且如果使用手动事务回滚,会出现异常:
org.springframework.transaction.NoTransactionException:
No transaction aspect-managed TransactionStatus in scope
事务统一的几种方式
1、直接使用@Transactional注解,且方法内没有try/catch,此种方式事务会正常回滚
@Transactional
@Override
public void test() {
WaStaff waStaff1 = new WaStaff();
waStaff1.setName("6666");
iWaStaffService.save(waStaff1);
//故意抛出一个异常
int a1 = 1/0;
}
2、方法内包含try/catch,向上抛出Exception异常,此种方式事务失效,不会进行自动回滚
@Transactional
@Override
public void test() throws Exception {
try {
WaStaff waStaff = new WaStaff();
waStaff.setName("8888");
iWaStaffService.save(waStaff);
int a2 = 1/0;
}catch (Exception e){
e.printStackTrace();
//不做任何处理,只抛出Exception,无法回滚
throw new Exception("账户类型未找到");
}
}
3、方法内包含try/catch,向上抛出RuntimeException异常或子类异常,此种方式事务会正常回滚
@Transactional
@Override
public void test() {
try {
WaStaff waStaff = new WaStaff();
waStaff.setName("8888");
iWaStaffService.save(waStaff);
int a2 = 1/0;
}catch (Exception e){
e.printStackTrace();
//抛出运行时异常或其子类异常,事务可以自动回滚
throw new RuntimeException("");
}
}
4、在try/catch中,进行手动回滚,事务会正常回滚
@Transactional
@Override
public void test() {
try {
WaStaff waStaff = new WaStaff();
waStaff.setName("8888");
iWaStaffService.save(waStaff);
int a2 = 1/0;
}catch (Exception e){
e.printStackTrace();
//在catch中,手动回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}
}
5、try/catch代码外层就出现了异常,事务会正常回滚,程序被阻断,不会向下运行
@Transactional
@Override
public void test() {
WaStaff waStaff1 = new WaStaff();
waStaff1.setName("6666");
iWaStaffService.save(waStaff1);
int a1 = 1/0;
try {
WaStaff waStaff = new WaStaff();
waStaff.setName("8888");
iWaStaffService.save(waStaff);
int a2 = 1/0;
}catch (Exception e){
e.printStackTrace();
}
}
嵌套事务
1、两个方法都加了@Transactional注解,子方法异常时,两个方法中的事务会正常回滚
@Transactional
@Override
public void test() {
WaStaff waStaff1 = new WaStaff();
waStaff1.setName("6666");
iWaStaffService.save(waStaff1);
this.test2();
}
@Transactional
public void test2(){
WaStaff waStaff = new WaStaff();
waStaff.setName("8888");
iWaStaffService.save(waStaff);
int a1 = 1/0;
}
2、子方法不加事务,上层方法加事务,也会自动回滚
@Transactional
@Override
public void test() {
WaStaff waStaff1 = new WaStaff();
waStaff1.setName("6666");
iWaStaffService.save(waStaff1);
this.test2();
}
public void test2(){
WaStaff waStaff = new WaStaff();
waStaff.setName("8888");
iWaStaffService.save(waStaff);
int a1 = 1/0;
}
3、上层方法不加事务,内部方法加,事务失效,且因为上层方法没有交给事务管理,内部方法做任何操作会无效
@Override
public void test() {
WaStaff waStaff1 = new WaStaff();
waStaff1.setName("6666");
iWaStaffService.save(waStaff1);
this.test2();
}
@Transactional
public void test2(){
WaStaff waStaff = new WaStaff();
waStaff.setName("8888");
iWaStaffService.save(waStaff);
int a1 = 1/0;
}
4、需要按之前的几种方式处理,只try/catch,并不会回滚
@Transactional
@Override
public void test() {
try {
WaStaff waStaff = new WaStaff();
waStaff.setName("6666");
iWaStaffService.save(waStaff);
int a1 = 1 / 0;
//内部代码被上一行代码阻断了,所以不会执行,数据库插入了666这条数据,未回滚
test2();
} catch (Exception e) {
e.printStackTrace();
}
}
public void test2() {
WaStaff waStaff = new WaStaff();
waStaff.setName("8888");
iWaStaffService.save(waStaff);
int a1 = 1 / 0;
}