使用姿势如下
/** * 总是非事务地执行,如果存在一个活动事务,则抛出异常。 * * @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); }