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

测试事务调用时,我们新建一个bean: PropagationDemo2,下面的support方法支持事务运行

@Component public class PropagationDemo2 { @Autowired private PropagationDemo propagationDemo; @Transactional(rollbackFor = Exception.class) public void support(int id) throws Exception { // 事务运行 propagationDemo.support(id); } }

对于非事务调用,则是直接在测试类中调用(请注意下面的call方法,调用的是两个不同bean中的support方法)

private void testSupport() { int id = 430; // 非事务方式,异常不会回滚 call("support无事务运行", id, propagationDemo::support); // 事务运行 id = 440; call("support事务运行", id, propagationDemo2::support); }

输出结果如下:

============ support无事务运行 start ========== support无事务运行 >>>> {id=430, name=初始化, money=200, is_deleted=false, create_at=2020-02-02 15:23:26.0, update_at=2020-02-02 15:23:26.0} support: after updateMoney name >>>> {id=430, name=更新, money=200, is_deleted=false, create_at=2020-02-02 15:23:26.0, update_at=2020-02-02 15:23:46.0} 事务回滚!!! support无事务运行 >>>> {id=430, name=更新, money=210, is_deleted=false, create_at=2020-02-02 15:23:26.0, update_at=2020-02-02 15:23:46.0} ============ support无事务运行 end ========== ============ support事务运行 start ========== support事务运行 >>>> {id=440, name=初始化, money=200, is_deleted=false, create_at=2020-02-02 15:23:26.0, update_at=2020-02-02 15:23:26.0} support: after updateMoney name >>>> {id=440, name=更新, money=200, is_deleted=false, create_at=2020-02-02 15:23:26.0, update_at=2020-02-02 15:23:46.0} 事务回滚!!! support事务运行 >>>> {id=440, name=初始化, money=200, is_deleted=false, create_at=2020-02-02 15:23:26.0, update_at=2020-02-02 15:23:26.0} ============ support事务运行 end ==========

从上面的输出,也可以得出结果:非事务执行时,不会回滚;事务执行时,回滚

3. MANDATORY

需要在一个正常的事务内执行,否则抛异常

使用姿势如下

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

这种传播属性的特点是这个方法必须在一个已有的事务中运行,所以我们的测试case也比较简单,不再事务中运行时会怎样?

private void testMandatory() { int id = 450; // 非事务方式,抛异常,这个必须在一个事务内部执行 call("mandatory非事务运行", id, propagationDemo::mandatory); }

输出结果

============ mandatory非事务运行 start ========== mandatory非事务运行 >>>> {id=450, name=初始化, money=200, is_deleted=false, create_at=2020-02-02 15:23:26.0, update_at=2020-02-02 15:23:26.0} No existing transaction found for transaction marked with propagation 'mandatory' mandatory非事务运行 >>>> {id=450, name=初始化, money=200, is_deleted=false, create_at=2020-02-02 15:23:26.0, update_at=2020-02-02 15:23:26.0} ============ mandatory非事务运行 end ==========

从上面的输出可知,直接抛出了异常,并不会执行方法内的逻辑

4. NOT_SUPPORT

这个比较有意思,被它标记的方法,总是非事务地执行,如果存在活动事务,则挂起

(实在是没有想到,有什么场景需要这种传播属性)

一个简单的使用case如下:

@Transactional(propagation = Propagation.NOT_SUPPORTED, rollbackFor = Exception.class) public void notSupport(int id) throws Exception { if (this.updateName(id)) { this.query("notSupport: after updateMoney name", id); if (this.updateMoney(id)) { return; } } throw new Exception("回滚!"); }

接下来需要好好的想一下我们的测试用例,首先是它需要在一个事务中调用,外部事物失败回滚,并不会影响上面这个方法的执行结果

我们在PropagationDemo2中,添加测试case如下

@Transactional(rollbackFor = Exception.class) public void notSupport(int id) throws Exception { // 挂起当前事务,以非事务方式运行 try { propagationDemo.notSupport(id); } catch (Exception e) { } propagationDemo.query("notSupportCall: ", id); propagationDemo.updateName(id, "外部更新"); propagationDemo.query("notSupportCall: ", id); throw new Exception("回滚"); }

输出结果如下

============ notSupport start ========== notSupport >>>> {id=460, name=初始化, money=200, is_deleted=false, create_at=2020-02-02 15:23:26.0, update_at=2020-02-02 15:23:26.0} notSupport: after updateMoney name >>>> {id=460, name=更新, money=200, is_deleted=false, create_at=2020-02-02 15:23:26.0, update_at=2020-02-02 15:23:46.0} notSupportCall: >>>> {id=460, name=更新, money=210, is_deleted=false, create_at=2020-02-02 15:23:26.0, update_at=2020-02-02 15:23:46.0} notSupportCall: >>>> {id=460, name=外部更新, money=210, is_deleted=false, create_at=2020-02-02 15:23:26.0, update_at=2020-02-02 15:23:46.0} 回滚 notSupport >>>> {id=460, name=更新, money=210, is_deleted=false, create_at=2020-02-02 15:23:26.0, update_at=2020-02-02 15:23:46.0} ============ notSupport end ==========

从上面输出可以看出

NOT_SUPPORT 标记的方法,属于非事务运行(因为抛异常,修改没有回滚)

外部事务回滚,不会影响其修改

5. NEVER

总是非事务地执行,如果存在一个活动事务,则抛出异常。

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

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