• Spring 事务管理


    1. 事务基本概述

    事务的特性

    逻辑上的一组操作-,组成这组事务的各个单元,要么全部成功,要么全部失败

    事务的特性(ACID)

    • 原子性:事务不可分割
    • 一致性:事务执行前后数据完整性保证一致
    • 隔离性:一个事务不能干扰其它事务
    • 持久性:事务一旦成功,数据就持久化到数据库
    不考虑隔离性(使用锁)引发的问题

    事务的并发引发的问题

    • 读问题
      • 脏读:一个事务读取另一个事务未提交的数据
      • 不可重复读:一个事务读取到另一个事务update的数据,导致两次读取的结果不一致
      • 虚读:一个事务读取到另一个事务insert或者delete的数
        据,导致两次读取的结果不一致
    • 写问题:丢失更新
    不同的锁引发不同类型的事务(事务隔离级别)
    1. 不支持事务
    2. read_uncommitted 未提交读,不能解决任何读问题
    3. read_committed 已提交读 ,不能读取未提交的事务,能够解决脏读
    4. repeateable_read 可重复读 ,能够保证两次读取的数据是一致的,能解决脏读和不可重复读
    5. serializable 可序列化 ,事务的最高级别,可以解决脏读、不可重复读和虚读

    2. Spring事务管理API

    1. 平台事务管理器PlateformTransactionManager

    PlateformTransactionManager是一个接口

    • DataSourceTransactionManager:使用JDBC管理事务
    • HibernateTransactionManager:使用Hibernate管理事务
    2. 事务定义信息TransactionDefinition
    • 事务定义:用于定义事务的相关信息:隔离级别,传播信息,超时信息,是否只读
    3. 事务状态TransactionStatus

    用于记录事务在执行过程中,事务的状态的对象

    4. 关系

    事务管理器更具事务定义来管理事务,在管理过程中产生事务状态

    3. Spring事务的传播行为

    事务的传播行为主要用来解决业务层方法相互调用的问题

    Spring提供了七中的事务传播行为

    • 保证多个操作在同一个事务中
      • PROPAGATION_REQUIRED:默认值,如果A中有事务,则使用A中的事务,如果没有事务则创建一个事务
      • PROPAGATION_SUPPORTS 如果A中有事务,则使用A中的事务,如果没有则不使用事务
      • PROPAGATION_MANDATORY 如果A中有事务,则使用A中的事务,如果没有,则报异常
    • 保证多个操作在不同事务中
      • PROPAGATION_REQUIRES_NEW:默认值,如果A中有事务,将A中 的事务挂起,创建新的事务,只包含自身操作,如果A中没有事务,则创建新事务包含自身操作
      • PROPAGATION_NOT_SUPPORTE 如果A中有事务,将A的事务挂起,不使用事务
      • PROPAGATION_NEVER 如果A中有事务,报异常
    • 嵌套式事务

    4. 编程式事务

    1. 配置平台事务管理器
    <!-- 配置事务管理器 -->
    <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    2. 配置事务模板
    <!-- 配置事务管理模板,简化事务控制 -->
    <bean name="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="transactionManager"></property>
    </bean>
    
    3. 注入业务层
    <!-- 配置AccountService -->
    <bean name="accountService" class="com.ranger.spring.tx.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
        <property name="transactionTemplate" ref="transactionTemplate"></property>
    </bean>
    
    4. 使用事务模板开启事务
    @Override
    public void transfer(Integer from, Integer to, double money) {
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
    
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus arg0) {
    
                accountDao.increaseMoney(to, money);
    
                // 开启 / 关闭 异常
                int i = 1/0;
    
                accountDao.decreaseMoney(from, money);
            }
        });
    }
    

    5. 声明式事务管理(常用)通过配置实现 使用AOP

    1. XML配置使用声明式事务管理

    不必再业务层添加事务管理代码

    1. 导入AOP相关的包

    1. 配置事务管理器

      <!-- 配置事务管理器 -->
      <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
          <property name="dataSource" ref="dataSource"></property>
      </bean>
      
    2. 配置事务管理通知

      <!-- 配置通知(增强) -->
      <tx:advice id="txAdvice" transaction-manager="transactionManager" >
          <tx:attributes>
              <!-- <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT"/>
          <tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT"/>
          <tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT"/>
          <tx:method name="find*" read-only="true"/> -->
              <tx:method name="*" propagation="REQUIRED"/>
          </tx:attributes>
      </tx:advice>
      
    3. 织入

      <!-- 织入(完成对目标对象的代理) -->
      <aop:config>
          <aop:pointcut expression="execution(* com.ranger.spring.tx.service.impl.AccountServiceImpl.transfer(..))" id="transferPointCut"/>
          <aop:advisor advice-ref="txAdvice" pointcut-ref="transferPointCut"/>
      
      </aop:config>
      
    2. 注解使用声明式事务

    只需配置相应bean 和开启注解,配置注解

    1. 配置事务管理器

      <!-- 配置事务管理器 -->
      <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
          <property name="dataSource" ref="dataSource"></property>
      </bean>
      
    2. 配置文件中开启事务注解、

      <!-- 开启事务注解 -->
      <tx:annotation-driven transaction-manager="transactionManager"/>
      
    3. 类上配置注解

      @Transactional(isolation=Isolation.DEFAULT)   
      public class AccountServiceImpl implements AccountService {
      	
      	private AccountDao accountDao;
      	
      	private TransactionTemplate transactionTemplate;
      	
      	public void setAccountDao(AccountDao accountDao) {
      		this.accountDao = accountDao;
      	}
      	
      	
      
      	public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
      		this.transactionTemplate = transactionTemplate;
      	}
          
          @Override
      	public void transfer(Integer from, Integer to, double money) {
      
              accountDao.increaseMoney(to, money);
      
              // 开启 / 关闭 异常
              int i = 1/0;
      
              accountDao.decreaseMoney(from, money);
      
      	}
      
      }
      
  • 相关阅读:
    MongoDB 安装和即基本操作
    技术型创业者easy遇到的三大问题
    Swoole源代码学习记录(十五)——Timer模块分析
    利用NSInvocation对方法进行抽象,实现对方法的加锁
    Atitit.hibernate体系结构大总结
    HDU
    程序猿工作效率的影响因素和管理者怎样推断
    Linux下tomcat使用
    [1204 寻找子串位置] 解题报告
    Team Foundation Server 2013 with Update 3 Install LOG
  • 原文地址:https://www.cnblogs.com/watertreestar/p/11740769.html
Copyright © 2020-2023  润新知