面向小白的SpringBoot的事务编写讲解

465 阅读2分钟

这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战

Spring给我们提供了事务的支持,就是编程式事务声明式事务,今天我们来了解下,使用编程事务你可以精确定义事务边界,使用声明式事务,可以与业务代码解耦合,怎么选择看各位小白们的需求。

编程式事务

编程式事务就是使用TransactionTemplate,采用编程的方式进行事务管理,用过接口的execute方法进行事务管理,我们可以看下面的示例:

@Override
public void run(String... args) throws Exception {
    log.info("事务之前Count:{}",getCount());
    transactionTemplate.execute(new TransactionCallback<Object>() {
        @Override
        public Object doInTransaction(TransactionStatus status) {
            jdbcTemplate.update("insert into Foo(ID,BAR) VALUES (10,'coca1')");
            log.info("事务中Count:{}",getCount());
            status.setRollbackOnly();
            return null;
        }
    });

    log.info("事务之后Count:{}", getCount());
}

这个示例中我在事务开启之前进行了一个查询,事务执行中进行了一个数据的插入,然后进行了事务的回滚,之后又进行了一次查询,我们可以来看下结果:

image.png

结果和预期的一样,我们可以看下这个方法:

image.png

我们可以看到这个方法是调用事务管理器帮助我们管理事务,执行事务如果没有异常,那就提交,如果有异常就回滚。

声明式事务

Spring也给我们提供了声明式事务,声明式事务是基于AOP操作的,就是类似于一个动态代理,在你执行方法的时候,本质上执行的却是代理的方法,代理的方法对你的方法进行包装,在方法前开启一个事务,然后在运行中根据实际情况进行提交或者回滚。

这个实际情况可以根据你的喜好,进行自定义,比如我们就对异常进行一个定义。当然你可以使用注解或者XMl的方式,在实际的开发中使用注解更为简单,就像这样:加一个事务注解就可以。

image.png

这里我进行了一个插入,然后手动抛了个异常,模拟效果,结果就是这条数据没有插入进去。

然后,我觉得这样玩不过瘾,我还想看看方法事务的嵌套调用的执行情况,我用一个没有事务的方法,调用一个有事务的方法结果会发生什么?

    @Override
    public void invokeInsertThenRollback() throws RollbackException {
        insertThenRollback();
      
}

结果是:有事务的方法回滚了,而一个没有事务的方法调用一个有事务的方法就没有回滚。 image.png

结论就是:外面嵌套的不影响里面的,是不是很有趣。

对,这才符合我们的逻辑,你也可以根据此案例进行尝试,看看会不会有其它更好玩的结果,欢迎你与我交流,我们一起成长。