spring事务传播的Propagation.REQUIRES_NEW以及NEVER MANDATORY验证,及其失效的诡异问题

科技资讯 投稿 6700 0 评论

spring事务传播的Propagation.REQUIRES_NEW以及NEVER MANDATORY验证,及其失效的诡异问题

NEVER

不使用事务,如果当前事务存在,则抛出异常

验证:

@Service public class PrService { @Autowired PrDao dao; @Transactional public void savea( { dao.a(;//保存第一条数据 saveb(; } @Transactional(propagation = Propagation.NEVER private void saveb( { dao.b(;//保存第二条数据 int i=1/0; } }

写一个controller调用这个savea方法,页面看到的是/ by zero,数据库中两条数据都没有插入进去,都回滚了。照说设置了Propagation.NEVER,应该saveb方法根本执行不了,报never的错。为什么执行了呢?

@Service
public class PrService {
    @Autowired
    PrDao dao;
    
    @Autowired
    PrService prService;
    
    @Transactional
    public void savea( {
        dao.a(;//保存第一条数据
        prService.saveb(;
    }

    @Transactional(propagation = Propagation.NEVER
    private void saveb( {
        dao.b(;//保存第二条数据
        int i=1/0;
    }
}

注意这里是  prService.saveb(和前面不同,但是居然在  dao.b(; 这一行报了一个空指针的错误,这就诡异了,这个dao明明上a方法里面还有值的,你知道是为什么吗?

public void saveb(

再次测试,看到期待的报错了:

Existing transaction found for transaction marked with propagation 'never'

 

MANDATORY

当前存在事务,则加入当前事务,如果当前事务不存在,则抛出异常。

@Service
public class PrService {
    @Autowired
    PrDao dao;
    
    @Autowired
    PrService prService;

    public void savea( {
        dao.a(;//保存第一条数据
        prService.saveb(;
    }

    @Transactional(propagation = Propagation.MANDATORY
    public void saveb( {
        dao.b(;//保存第二条数据
    }
}

或者直接把MANDATORY放在a方法上也会报错:

@Service public class PrService { @Transactional(propagation = Propagation.MANDATORY public void savea( { } }

报错如下

No existing transaction found for transaction marked with propagation 'mandatory'

 

创建一个新事务,如果存在当前事务,则挂起该事务。

可以理解为设置事务传播类型为REQUIRES_NEW的方法,在执行时,不论当前是否存在事务,总是会新建一个事务。

现在写一个demo验证,a方法调用b方法,希望b方法里面异常了且事务回滚,a方法里面不回滚

下面验证:

同样为了在避免事务失效,在代理对象上调用方法,将被调用的方法放到一个单独的类中:

@Service public class PrService { @Autowired PrDao dao; @Autowired SaveBService saveBService; @Transactional public void savea( { dao.a(;//插入第一条数据 saveBService.saveb(; } }

@Service
public class SaveBService {
    @Autowired
    PrDao dao;

    @Transactional(propagation = Propagation.REQUIRES_NEW
    public void saveb( {
        dao.b(;//插入第二条数据
        int i = 1/0;
    }
}

这里PrService的savea方法调用SaveBService的saveb方法,写一个controller访问savea方法,页面看到一个异常 / by zero,再检查数据库,两条数据都有没有插入进去。这是为什么呢?看上去第二个方法已经写到独立的类中了。

    @Transactional
    public void savea( {
        dao.a(;//插入第一条数据
        try {
            saveBService.saveb(;
        }catch (Exception e {
            System.out.println("some error";
        }
    }

再次测试,第二条数据没有插入,第一条数据插入到数据库了,页面也看不到报错了。

 

编程笔记 » spring事务传播的Propagation.REQUIRES_NEW以及NEVER MANDATORY验证,及其失效的诡异问题

赞同 (25) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽