zoukankan      html  css  js  c++  java
  • spring 事务管理机制

    1. spring 事务管理抽象

    spring 的事务策略机制的核心就是 org.springframework.transaction.PlatformTransactionManager 接口。

    public interface PlatformTransactionManager {
    
        TransactionStatus getTransaction(
                TransactionDefinition definition) throws TransactionException;
    
        void commit(TransactionStatus status) throws TransactionException;
    
        void rollback(TransactionStatus status) throws TransactionException;
    }

    PlatformTransactionManager 的方法运行出错时,都会抛出 TransactionException 异常,而这个异常几乎都是致命的,不可修复的。

    getTransaction(..) 方法会根据对 TransactionDefinition 对象的处理结果返回一个 TransactionStatus 对象。 TransactionStatus 对象则表示一个事务的状态,表示该事务是否是一个新的事务,是否 commit 或 rollback 等。

    public interface TransactionStatus extends SavepointManager {
    
        /**
         * 是新的事务还是已存在的事务
         */
        boolean isNewTransaction();
    
        /**
         * 是否有 savePoint*/
        boolean hasSavepoint();
    
        /**
         * Set the transaction rollback-only. */
        void setRollbackOnly();
    
        /**
         * 该事务是否已标记 rollback-only
         */
        boolean isRollbackOnly();
    
        /**
         * Flush the underlying session to the datastore, if applicable:
         * for example, all affected Hibernate/JPA sessions.
         */
        void flush();
    
        /**
         * Return whether this transaction is completed, that is,
         * whether it has already been committed or rolled back.*/
        boolean isCompleted();
    
    }

    TransactionDefinition 接口则定义了下面几个属性

    • Isolation 隔离性级别
    • Propagation 传播属性:在事务上下文存在或者不存在时,可以指定方法的 tansaction 行为(新创建,使用已有的还是抛出异常)
    • Timeout: 超时时间
      • 时间单位 s
      • 表示在该时间内如果函数还没有执行完成,就会 rollback
    • Read-only status:  当代码中只是读取数据,而不修改数据时,可以使用该属性。

    在和 mybatis 配合时,一般会使用 DataSourceTransactionManager, 它们的继承关系如下:

     下面就以 spring-mybatis 给出配置事务的实例

    1. 定义 DataSource

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <property name="driverClassName" value="${jdbc.driver}" />
            <property name="url" value="${jdbc.url}" />
            <property name="username" value="${jdbc.username}" />
            <property name="password" value="${jdbc.password}" />
            <property name="initialSize" value="${jdbc.initialSize}"></property>
            <property name="maxActive" value="${jdbc.maxActive}"></property>
            <property name="maxIdle" value="${jdbc.maxIdle}"></property>
            <property name="minIdle" value="${jdbc.minIdle}"></property>
            <property name="maxWait" value="${jdbc.maxWait}"></property>
        </bean>

    2. 定义 DataSourceTransactionManager bean, 此时需要引用前面配置的 DataSource Bean

        <!-- 声明事务管理器 -->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource"/>
        </bean>

    3. 如果是使用基于注解的 spring 声明式事务管理, 需要如下配置

    <tx:annotation-driven transaction-manager="transactionManager"/>

    2. 声明式事务管理

    2.1 对声明式事务管理机制的理解

    spring 声明式事务管理是使用 AOP 代理实现的, transaction advice 事务通知是由元数据(注解或者 XML)驱动的。(待完善。。。)

    2.2 @Transactional 注解

    在上节最后我们已经说明,要使用基于注解的 spring 声明式事务,需要在 xml 中使用 <tx:annotation 配置。

    <tx:annotation-driven transaction-manager="transactionManager"/>

    <tx:annotation-driven 配置

    XML 属性 默认值 描述
    transaction-manager
    transactionManager
    如果声明的transaction manager 名字不是
    transactionManager才需要配置
    mode proxy 有 proxy, aspectj 两种模式可选
    proxy-target-class false

    只对 proxy 模式有效。是基于接口的还是基于类的代理被创建。

    true,那么基于类的代理将起作用(这时需要cglib库)

    false,使用标准的JDK 基于接口的代理

    order Ordered.LOWEST_PRECEDENCE

    Defines the order of the transaction advice that is applied

    to beans annotated with @Transactional.

    @Transactional 配置

    @Transactional 既可以注解在 class 上,也可以注解在 method 上。

    有下面几点需要注意

    • 尽量注解在具体实现类中(大部分情况是 service 实现类),注解在接口上也可以,但还需要其他的配置才能生效,此处不会讲述。
    • 在注解到 method 上时,该 method 需要是 public 修饰符修饰,在 proxy 默认模式下,注解在 package或者 private 方法上不会报错,但也不会生效。

    参考链接: https://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/transaction.html#tx-multiple-tx-mgrs-with-attransactional

  • 相关阅读:
    【线段树合并】联通分量计数
    莫队算法
    Ubuntu实用软件安装[转]
    装系统·折腾记
    Qt环境配置 + Qt使用教程
    Google题解
    隐含马尔科夫模型
    Pythonの坑
    C++11并发编程个人小结
    微软2017年预科生计划在线编程笔试
  • 原文地址:https://www.cnblogs.com/reycg-blog/p/7883634.html
Copyright © 2011-2022 走看看