Spring事务之五(应用场景分析)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhuqiuhui/article/details/70307106

更多文章:http://zhuqiuhui.space/

场景一 Exception回滚

Case 1:插入操作回滚
    @Transactional
    public int insertUser(User user) {
        int num = iUserDao.insertUser(user);
        if (num > 0) {
            throw new RuntimeException();
        }
        return num;
    }
  
Case 2: 插入操作不回滚
    @Transactional
    public int insertUser(User user) throws Exception{
        int num = iUserDao.insertUser(user);
        if (num > 0) {
            throw new Exception();
        }
        return num;
    }
  
Case 3: 插入操作回滚
    @Transactional(rollbackFor = Exception.class)
    public int insertUser(User user) throws Exception{
        int num = iUserDao.insertUser(user);
        if (num > 0) {
            throw new Exception();
        }
        return num;
    }

场景二 propagation属性

Case 1: (1)调用insertUser的方法不在事务中,正常插入。
        (2)调用insertUser的方法在事务中,不会插入。
         解释: PROPAGATION_SUPPORTS表示:如果当前在事务中,即以事务的形式运行,如果当前不在一个事务中,那么就以非事务的形式运行。只读标志只在事务启动时应用。若调用该方法的方法不在事务中,则就执行成功(因为没有启动任何事务,所以只读标志被忽略)。若在事务中,会回滚插入操作。
  
    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    public int insertUser(User user) {
        int num = iUserDao.insertUser(user);
        return num;
    }
  
Case 2: 抛出异常:java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
  
   @Transactional(readOnly = true, propagation = Propagation.REQUIRED)
   public int insertUser(User user) throws Exception{
       int num = iUserDao.insertUser(user);
       return num;
   }
  
Case 3:(1)执行失败(2)执行失败  抛出异常java.lang.RuntimeException
    (重要:此处三个函数在同一个类文件中,异常必须抛出,由Spring来捕捉)
    @Transactional(propagation= Propagation.REQUIRED)
    public void testModifyUser(User user) throws Exception {
            insertUser(user); -------(1)
            user.setId(13);
            updateUser(user); -------(2)
    }
     
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    public int insertUser(User user) throws Exception{
        int num = iUserDao.insertUser(user);
        return num;
    }
  
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    public int updateUser(User user) throws Exception{
        //更新语句......
        throw new RuntimeException();    //运行时异常 ---------(3)
    }
注意:(3)处替换为“throw new FileNotFoundException();”或者“throw new Exception();”(非运行时异常),(1)(2)均执行成功,并抛出相应的异常!
  
Case 4:(1)执行失败(2)执行失败  抛出异常java.lang.RuntimeException
    (重要:此处三个函数在同一个类文件中,异常必须抛出,由Spring来捕捉才能回滚)
    @Transactional(propagation= Propagation.REQUIRED)
    public void testModifyUser(User user) throws Exception {
            insertUser(user); -------(1)
            user.setId(13);
            updateUser(user); -------(2)
    }
     
    public int insertUser(User user) throws Exception{
        int num = iUserDao.insertUser(user);
        return num;
    }
 
    public int updateUser(User user) throws Exception{
        //更新语句......
        int cnt = iUserDao.updateUser(newvalue, conds);
        if(cnt > 0) {
            throw new RuntimeException(); ---------(3)
        }
    }
  注意:(3)处替换为“throw new FileNotFoundException();”或者“throw new Exception();”,(1)(2)均执行成功,并抛出相应的异常!
  

场景三 业务场景

Case 1: (1)(2)都没有成功,并抛出java.lang.RuntimeException异常
    (重要:此处四个函数在同一个类文件中,异常必须抛出,由Spring来捕捉才能回滚)
    @Transactional
    public void testModifyUser(User user) throws Exception {
            insertUser(user); -------(1)
            B(user);          -------(2)
    }
  
    // 私有方法
    private void B(User user) throws Exception {
            user.setId(13);
            updateUser(user);
    }
     
    public int insertUser(User user) throws Exception{
        int num = iUserDao.insertUser(user);
        return num;
    }
     
    @Transactional
    public int updateUser(User user) throws Exception{
        //更新语句......
        int cnt = iUserDao.updateUser(newvalue, conds);
        if(cnt > 0) {
            throw new RuntimeException(); ---------(3)
        }
    }
注意一:第(3)处替换为“throw new FileNotFoundException();”或者“throw new Exception();”,(1)(2)均执行成功,并抛出相应的异常!
注意二:若在函数public int updateUser(User user) throws Exception加上“@Transactional(rollbackFor = Exception.class)”,执行结果同上,因为@Transactional默认的传播是:Propagation.REQUIRED,即表明当前如果有事务, 那么加入事务, 没有的话新建一个,当前是有事务的,不用新建,也即是说“@Transactional(rollbackFor = Exception.class)”不起任何作用。
  
  
Case 2:(1)和(2)处均执行不成功,并抛出java.lang.RuntimeException异常
类UserServiceImpl:
public class UserServiceImpl implements IUserService {
  
    @Resource
    IUser2Service iUser2Service;
     
    @Resource(name = "userDao")
    IUserDao iUserDao;
    @Transactional
    public void testModifyUser(User user) throws Exception {
            int num = iUserDao.insertUser(user);        -------(1)
            System.out.println("effect " + num + " rows!");
            B();                                        -------(2)
    }
  
    // 私有方法
    private void B() throws Exception {
            iUser2Service.deleteUserById(25);
    }
     
    //......
}
  
类User2ServiceImpl:
@Service
public class User2ServiceImpl implements IUser2Service {
 
    @Resource(name = "userDao")
    IUserDao iUserDao;
 
    @Transactional                     -------------------------(3)
    public int deleteUserById(int id) throws Exception {
        Map<String, Object> conds = Maps.newHashMap();
        conds.put("id", id);
        int cnt = iUserDao.deleteUserById(conds);
        if(cnt > 0) {
            throw new RuntimeException();   ---------------------(4)
        }
        return cnt;
    }
}
  
 注意:情况一:第(4)处替换为“throw new FileNotFoundException();”或者“throw new Exception();”,(1)(2)均执行成功,并抛出相应的异常!
      情况二:第(3)处去掉“@Transactional”,即不加事务,(1)和(2)处均执行不成功,并抛出java.lang.RuntimeException异常!
      情况三:第(3)处去掉“@Transactional”,同时第(4)处替换为“throw new FileNotFoundException();”或者“throw new Exception();”,则(1)(2)均执行成功,并抛出相应的异常!
      情况四:第(3)处替换为“@Transactional(rollbackFor = Exception.class)”,(1)和(2)处均执行不成功,并抛出java.lang.RuntimeException异常!
      情况五:第(3)处替换为“@Transactional(rollbackFor = Exception.class)”,同时第(4)处替换为“throw new FileNotFoundException();”或者“throw new Exception();”,则(1)(2)均执行失败,并抛出相应的异常,同时抛出“org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only”异常!





展开阅读全文

没有更多推荐了,返回首页