Spring 知识点总结 之 事务管理

Spring的事务管理


事务

逻辑上的一组操作,要不全部成功,要不全部失败。

  • 原子性
  • 隔离性
  • 一致性
    • 几个并行执行的事务,其执行结果必须与按某一顺序串行执行的结果相一致
  • 持久性

在没有事务导致的问题

  • 读问题
    • 脏读
      • 读到了未提交的数据
    • 虚读
      • 读到了其他事务提交的数据,导致两次查询结果集数量不同
    • 不可重复读
      • 读到了其他事务提交的数据,导致统一条记录,两次查询结果不同
  • 写问题
    • 丢失更新

解决方法

  • 读问题 通过设置事务的隔离级别解决。
  • 写问题 通过乐观锁、悲观锁解决。

Spring的事务管理的API

  • PlatformTransactionManager 事务管理器
  • TransactionDefinition 事务隔离级别、传播策略
  • TransactionStatus 事务状态
  • 关系:平台事务管理器真正管理事务对象.根据事务定义的信息TransactionDefinition.进行事务管理.在管理事务中产生一些状态.将状态记录到TransactionStatus中.

事务管理器常见的实现类(与使用的数据库连接池有关)

  • DataSourceTrsansactionManager (Spring JDBC 或 Mybatis)
  • HibernateTransactionManager (Hibernate)
  • JpaTransactionManager (JPA)

    类结构图

  • 顶层接口方法
    • getTransaction(TransactionDefinition)
    • commit(TransactionStatus)
    • rollback(TransactionStatus)

事务定义


  // IntelliJ API Decompiler stub source generated from a class file
  // Implementation of methods is not available

package org.springframework.transaction;

public interface TransactionDefinition {
    int PROPAGATION_REQUIRED = 0;
    int PROPAGATION_SUPPORTS = 1;
    int PROPAGATION_MANDATORY = 2;
    int PROPAGATION_REQUIRES_NEW = 3;
    int PROPAGATION_NOT_SUPPORTED = 4;
    int PROPAGATION_NEVER = 5;
    int PROPAGATION_NESTED = 6;
    int ISOLATION_DEFAULT = -1;
    int ISOLATION_READ_UNCOMMITTED = 1;
    int ISOLATION_READ_COMMITTED = 2;
    int ISOLATION_REPEATABLE_READ = 4;
    int ISOLATION_SERIALIZABLE = 8;
    int TIMEOUT_DEFAULT = -1;

    int getPropagationBehavior();

    int getIsolationLevel();

    int getTimeout();

    boolean isReadOnly();

    java.lang.String getName();
}
  • ISOLATION_* :事务隔离级别

    • ISOLATION_DEFAUTL :
    • ISOLATION_READ_UNCOMMITTED
    • ISOLATION_READ_COMMITTED
    • ISOLATION_REPEATABLE_READ
    • ISOLATION_SERIALIZABLE
  • PROPAGATION_*: 事务传播行为:A、B为使用 同一个数据库连接的方法。

    • PROPAGATION_REQUIRED :A中有事务,使用A中的事务.如果没有B就会开启一个新的事务,将A包含进来.(保证A,B在一个事务中)
    • PROPAGATION_SUPPORTS :A中有事务,使用A中的事务.如果A中没有事务.那么B也不使用事务.
    • PROPAGATION_MANDATORY :A中有事务,使用A中的事务.如果A没有事务.抛出异常.

    • PROPAGATION_REQUIRES_NEW :A中有事务,将A中的事务挂起.创建一个新的事务.(保证A,B没有在一个事务中)

    • PROPAGATION_NOT_SUPPORTED :A中有事务,将A中的事务挂起.
    • PROPAGATION_NEVER :A中有事务,抛出异常.

    • PROPAGATION_NESTED :嵌套事务.当A执行之后,就会在这个位置设置一个保存点.如果B没有问题.执行通过.如果B出现异常,运行客户根据需求回滚(选择回滚到保存点或者是最初始状态)


TransactionStatus 事务的状态

    boolean isNewTransaction();
    boolean hasSavepoint();
    void setRollbackOnly();
    boolean isRollbackOnly();
    void flush();
    boolean isCompleted();

Spring 事务配置(编程式事务)

不做赘述,了解即可(很少使用)

Spring为了简化事务管理的代码:提供了模板类.TransactionTemplate.

步骤一:配置一个事务管理器.
    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

步骤二:配置事务管理的模板:
    <!-- 配置事务管理的模板 -->
    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="transactionManager"/>
    </bean>

步骤三:在需要进行事务管理的类中,注入事务管理的模板.
    <!-- 配置业务层的类 -->
    <bean id="accountService" class="com.itheima.spring.demo1.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"/>
        <!-- 注入事务管理的模板 -->
        <property name="transactionTemplate" ref="transactionTemplate"/>
    </bean>

步骤四:在业务层使用模板管理事务:
    @Override
    public void transfer(final String out, final String in, final Double money) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                accountDao.outMoney(out, money);
                int d = 1 / 0;
                accountDao.inMoney(in, money);
            }
        });
    }

Spring 事务配置 (声明式事务 使用AOP实现)

  • Spring 通过ProxyFactoryBean 实现自动代理
    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 配置生成代理:增强业务层类 -->
    <bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <!-- 配置目标类 -->
        <property name="target" ref="accountService"/>
        <!-- 注入事务管理器 -->
        <property name="transactionManager" ref="transactionManager"/>
        <!-- 配置事务的相关属性 -->
        <property name="transactionAttributes">
            <!-- prop格式:PROPAGATION,ISOLATION,readOnly,-Exception,+Exception -->
            <props>
                <prop key="transfer">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>
  • 通过 AspectJ 实现代理(重点掌握)
<!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!-- 配置事务增强 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
<!-- 
                propagation :传播行为
                isolation   :隔离级别
                read-only   :是否只读
                timeout     :超时信息
                rollback-for:发生哪些异常回滚.
                no-rollback-for:发生哪些异常不回滚.
             -->
            <tx:method name="transfer" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

    <!-- 配置AOP切面产生代理 -->
    <aop:config>
        <aop:pointcut expression="execution(* com.itheima.spring.demo3.AccountService+.*(..))" id="pointcut1"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
    </aop:config>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值