springboot使用@Transactional实现本地事务

springboot中实现本地事务很简单:

1.启动类中开启事务支持的注解  @EnableTransactionManagement

2.在需要事务的方法上加@Transactional注解

//会在此处写几段代码进行比较说明

//1.抛出一个Exception

//结果是不会回滚

@Transactional

public void test1(User user) throws Exception{

    userService.add(user);

    throw new Exception("抛出异常");

}


//2.抛出一个RuntimeException

//结果是回滚

@Transactional

public void test2(User user) throws Exception{

    userService.add(user);

    throw new RuntimeException("抛出异常");

}

//3.抛出一个Exception,注解@Transactional(rollbackFor=Exception.class)

//结果是回滚

@Transactional(rollbackFor=Exception.class)

public void test1(User user) throws Exception{

    userService.add(user);

    throw new Exception("抛出异常");

}

结论一:事务默认回滚的是unchecked异常,如RuntimeException; 不会处理checked异常,如Exception

解决办法:注解@Transactional上添加说明回滚的异常,如rollbackFor=Exception.class

//4.使用try catch捕获异常,但catch内不抛出

//结果是不会回滚

@Transactional(rollbackFor=Exception.class)

public void test1(User user) throws Exception{

    try{

        userService.add(user);

        throw new Exception("抛出异常");

    }catch(Exception e){

        e.printStackTrace();

    }   

}

//5.使用try catch捕获异常,catch内抛出

//结果是回滚

@Transactional(rollbackFor=Exception.class)

public void test1(User user) throws Exception{

    try{

        userService.add(user);

        throw new Exception("抛出异常");

    }catch(Exception e){

        e.printStackTrace();

        throw e;

    }   

}

结论二: try catch捕获到try中出现的异常,会在catch内进行处理, 但需要在catch中主动将该异常抛出,否则事务无法捕获到该异常进行回滚(可以理解为try catch捕获异常会将该异常吃了,想要再让事务发现该异常,需要catch中主动抛出)

解决办法: catch(Exception e){throw e}.

//6.try catch捕获异常,不抛出,进行手动回滚,不指定回滚异常类型

//结果是回滚

@Transactional

public void test1(User user) {

    try{

        userService.add(user);

        throw new Exception("抛出异常");

    }catch(Exception e){

        TransactionAspecSupport.currentTransactionStatus().setRollbackOnly();

        e.printStackTrace();

    }   

}

//7.try catch捕获异常,不抛出,进行手动回滚,指定回滚异常类型

//结果是回滚

@Transactional(rollbackFor=Exception.class)

public void test1(User user) {

    try{

        userService.add(user);

        throw new Exception("抛出异常");

    }catch(Exception e){

        TransactionAspecSupport.currentTransactionStatus().setRollbackOnly();

        e.printStackTrace();

    }   

}

结论三:不抛出异常,可直接在try catch内进行处理, 手动回滚事务

解决办法:catch内添加TransactionAspecSupport.currentTransactionStatus().setRollbackOnly();

并且因为没有抛出异常,可不指定rollbackfor

注意: (1)事务控制只能是public方法 (2)本地事务控制的方法,在执行完所有结果之前是没有提交的,但是在抛出异常之前执行过的操作(如insert),会占用数据库的主键id

猜你喜欢

转载自blog.csdn.net/xiao_Ray/article/details/89280976