美文网首页
几个直击灵魂的Spring拷问(四)

几个直击灵魂的Spring拷问(四)

作者: 千淘萬漉 | 来源:发表于2020-09-28 09:29 被阅读0次

    这一篇来重点讲讲Spring中的事务。

    1、Spring和事务的关系:

    • 事务性资源:如关系型数据库Mysql、Oracle、某些消息队列中间件等,因为它们本身支持事务,也能够处理事务。
    • Spring不是事务性资源,但是它可以管理事务性资源,所以Spring和事务之间是管理关系。

    2、Spring事务三要素:

    • 数据源:表示具体的事务性资源,是事务的真正处理者,如MySQL等。
    • 事务管理器:像一个大管家,从整体上管理事务的处理过程,如打开、提交、回滚等。
    • 事务应用和属性配置:像一个标识符,表明哪些方法要参与事务,如何参与事务,以及一些相关属性如隔离级别、超时时间等。

    3、事务的基本原理:

    Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行:

    • 获取连接 Connection con = DriverManager.getConnection()
    • 开启事务con.setAutoCommit(true/false);
    • 执行CRUD
    • 提交事务/回滚事务 con.commit() / con.rollback();
    • 关闭连接 conn.close();

    使用Spring的事务管理功能后,我们可以不再写步骤 2 和 4 的代码,而是由Spirng 自动完成。那么Spring是如何在我们书写的 CRUD 之前和之后开启事务和关闭事务的呢?解决这个问题,也就可以从整体上理解Spring的事务管理实现原理了。

    以注解方式为例子:
    1、配置文件开启注解驱动,在相关的类和方法上通过注解@Transactional标识。
    2、spring 在启动的时候会去解析生成相关的bean,这时候会查看拥有相关注解的类和方法,并且为这些类和方法生成代理,并根据@Transaction的相关参数进行相关配置注入,这样就在代理中为我们把相关的事务处理掉了(开启正常提交事务,异常回滚事务)。
    3、真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。

    4.事务类型

    分为两种:编程式事务、声明式事务

    (1)编程式事务

    编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。很少用,但是可以看下官网的例子:

    public class SimpleService implements Service {
    
        private final TransactionTemplate transactionTemplate;
        
        // 使用构造对transactionTemplate进行初始化
        // 需要提供一个transactionManager
        public SimpleService(PlatformTransactionManager transactionManager) {
            this.transactionTemplate = new  TransactionTemplate(transactionManager);
        }
    
        public Object someServiceMethod() {
            return transactionTemplate.execute(new TransactionCallback() {
                public Object doInTransaction(TransactionStatus status) {
                    // 这里实现自己的相关业务逻辑
                    updateOperation1();
                    return resultOfUpdateOperation2();
                }
            });
        }
    }
    

    在上面的例子中,显示的使用了 TransactionTemplate 来完成事务管理,通过实现 TransactionCallback 接口并在其 doInTransaction 方法中完成了我们对业务的处理。我们可以大概看下 TransactionTemplate的execute 方法的实现,实际上就是通过一个 TransactionCallback 封装了业务逻辑,然后 TransactionTemplate 会在事务的上下文中调用:

    public <T> T execute(TransactionCallback<T> action) throws TransactionException {
            Assert.state(this.transactionManager != null, "No PlatformTransactionManager set");
    
            if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
                return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
            }
            else {
                // 1.通过事务管理器开启事务
                TransactionStatus status = this.transactionManager.getTransaction(this);
                T result;
                try {
                    // 2.执行传入的业务逻辑
                    result = action.doInTransaction(status);
                }
                catch (RuntimeException | Error ex) {
                    // 3.出现异常,进行回滚
                    rollbackOnException(status, ex);
                    throw ex;
                }
                catch (Throwable ex) {
                    // 3.出现异常,进行回滚
                    rollbackOnException(status, ex);
                    throw new UndeclaredThrowableException(ex, 
                         "TransactionCallback threw undeclared checked exception");
                }
                // 4.正常执行完成的话,提交事务
                this.transactionManager.commit(status);
                return result;
            }
        }
    

    (2)声明式事务

    声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。

    显然声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式。声明式事务管理也有两种常用的方式,一种是基于xml配置文件,另一种就是基于@Transactional注解。显然基于注解的方式更简单易用,更清爽。

    Spring事务配置

    spring Boot 使用事务非常简单,首先使用注解 @EnableTransactionManagement 开启事务支持后,然后在访问数据库的Service方法上添加注解 @Transactional 便可。

    相关文章

      网友评论

          本文标题:几个直击灵魂的Spring拷问(四)

          本文链接:https://www.haomeiwen.com/subject/auutuktx.html