SpringBoot系列教程之事务传递属性 (3)

使用姿势如下

/** * 总是非事务地执行,如果存在一个活动事务,则抛出异常。 * * @param id * @throws Exception */ @Transactional(propagation = Propagation.NEVER, rollbackFor = Exception.class) public void never(int id) throws Exception { if (this.updateName(id)) { this.query("notSupport: after updateMoney name", id); if (this.updateMoney(id)) { return; } } }

我们的测试就比较简单了,如果在事务中运行,是不是会抛异常

在PropagationDemo2中,添加一个事务调用方法

@Transactional(rollbackFor = Exception.class) public void never(int id) throws Exception { propagationDemo.never(id); }

测试代码

private void testNever() { int id = 470; call("never非事务", id, propagationDemo2::never); }

输出结果

============ never非事务 start ========== never非事务 >>>> {id=470, name=初始化, money=200, is_deleted=false, create_at=2020-02-02 15:23:26.0, update_at=2020-02-02 15:23:26.0} Existing transaction found for transaction marked with propagation 'never' never非事务 >>>> {id=470, name=初始化, money=200, is_deleted=false, create_at=2020-02-02 15:23:26.0, update_at=2020-02-02 15:23:26.0} ============ never非事务 end ==========

直接抛出了异常,并没有执行方法内的业务逻辑

6. NESTED

其主要特点如下

如果不存在事务,则开启一个事务运行

如果存在事务,则运行一个嵌套事务;

上面提出了一个嵌套事务的概念,什么是嵌套事务呢?

一个简单的理解:外部事务回滚,内部事务也会被回滚;内部事务回滚,外部无问题,并不会回滚外部事务

接下来设计两个测试用例,一个是内部事务回滚;一个是外部事务回滚

a. case1 内部事务回滚 @Transactional(propagation = Propagation.NESTED, rollbackFor = Exception.class) public void nested(int id) throws Exception { if (this.updateName(id)) { this.query("nested: after updateMoney name", id); if (this.updateMoney(id)) { return; } } throw new Exception("事务回滚!!!"); }

在PropagationDemo2这个bean中,添加一个外部事务,捕获上面方法的异常,因此外部执行正常

@Transactional(rollbackFor = Exception.class) public void nested(int id) throws Exception { propagationDemo.updateName(id, "外部事务修改"); propagationDemo.query("nestedCall: ", id); try { propagationDemo.nested(id); } catch (Exception e) { } }

测试代码

private void testNested() { int id = 480; call("nested事务", id, propagationDemo2::nested); }

输出结果如下

============ nested事务 start ========== nested事务 >>>> {id=480, name=初始化, money=200, is_deleted=false, create_at=2020-02-02 15:23:26.0, update_at=2020-02-02 15:23:26.0} nestedCall: >>>> {id=480, name=外部事务修改, money=200, is_deleted=false, create_at=2020-02-02 15:23:26.0, update_at=2020-02-02 15:23:46.0} nested: after updateMoney name >>>> {id=480, name=更新, money=200, is_deleted=false, create_at=2020-02-02 15:23:26.0, update_at=2020-02-02 15:23:46.0} nested事务 >>>> {id=480, name=外部事务修改, money=200, is_deleted=false, create_at=2020-02-02 15:23:26.0, update_at=2020-02-02 15:23:46.0} ============ nested事务 end ==========

仔细看一下上面的结果,外部事务修改的结果都被保存了,内部事务的修改被回滚了,没有影响最终的结果

b. case2 外部事务回滚 @Transactional(propagation = Propagation.NESTED, rollbackFor = Exception.class) public void nested2(int id) throws Exception { if (this.updateName(id)) { this.query("nested: after updateMoney name", id); if (this.updateMoney(id)) { return; } } }

在PropagationDemo2这个bean中,添加一个外部事务,内部事务正常,但是外部事务抛异常,主动回滚

@Transactional(rollbackFor = Exception.class) public void nested2(int id) throws Exception { // 嵌套事务,外部回滚,会同步回滚内部事务 propagationDemo.updateName(id, "外部事务修改"); propagationDemo.query("nestedCall: ", id); propagationDemo.nested2(id); throw new Exception("事务回滚"); }

测试代码

private void testNested() { int id = 490; call("nested事务2", id, propagationDemo2::nested2); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjdfj.html