美文网首页
Spring事务管理入门

Spring事务管理入门

作者: stoneyang94 | 来源:发表于2018-05-21 16:07 被阅读0次

    说明:本文主要内容来自慕课网。配合视频食用口味更佳。
    主要是顺着已经学习的视频顺序总结一遍,以深化理解和方便日后复习。

    概念简析

    事务

    逻辑的一组操作,要么一起成功,要么一起失败。

    事务的特性 ACID

    • 原子性:事务是一个不可分割的工作单位。事务中的操作要么一起成功,要么一起失败。
    • 一致性:事务前后数据的完整性必须保持一致。
    • 隔离性:多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务干扰。可以通过设置隔离级别来实现。
    • 持久性:一个事务一旦被提交,那么数据库中数据的改变是永久性的。即使数据库发生故障也不该对其有影响。

    spring中事务管理的api

    • PlatformTransactionManager:事务管理器
      包含了事务的提交、回滚等管理。
    • TransactionDefinition:事务定义信息
      包含了事务的隔离级别、传播、超时信息等。
    • TransactionStatus:事务具体运行状态
      包含了事务是否有保存点、是不是新事务等状态信息

    PlatformTransactionManager

    是interface,有一些具体的实现类,比如datasourceTransactionManager。
    spring为不同的持久化框架提供了不同的PlatformTransactionManager。以最常用的举例。

    框架 事务
    spring jdbc或ibatis、mybatis org.springframework.jdbc.datasource.DataSourceTransactionManager
    Hibernate org.springframework.orm.hibernate3.HibernateTransactionManager

    TransactionDefinition

    隔离级别

    • 隔离级别相关的常量,以ISOLATION开头。

    • 数据库在查询数据时,由于种种原因会发生以下三种问题.

      • 脏读:一个事务读取了另一个事务改写但是还没提交的数据。如果这些数据被回滚,则读到的数据是无效的。
      • 不可重复读:在同一个事务中,多次读取同一个数据返回的结果不同。
      • 幻读:一个事务读取了几行数据后,另一个事务插入了一些记录。在后来的查询中,第一个事务就会发现一些原来不存在的记录。
    • 事务的隔离级别: 就是为了解决以上问题设定的事务相关的属性

    隔离级别 含义
    DEFAULT 使用后端数据库默认的隔离级别(spring中得选择项)
    READ_UNCOMMITED 允许读取还没提交的已改变了的数据,可能导致脏读、幻读、不可重复读。
    READ_COMMITED 允许在并发事务已经提交后读取,可防止脏读。但不可防止幻读和不可重复读。
    REPEATABLE_READ 对相同字段的多次读取,结果是一致的,除非数据被事务本身改变。可防止脏读、不可重复读,但不可防止幻读。
    SERIALIZABLE 完全服从ACID的隔离级别,可防止脏读、幻读、不可重复读。这在所有隔离级别中是最慢的,因为它是通过完全锁定在事务中涉及的数据表来完成的。是不可能出现并发访问的情况。
    • 默认隔离级别举例:
      mysql:REPEATABLE_READ
      oracle:READ_COMMITED
      Spring中默认的隔离级别就是使用的底层数据库的隔离级别

    传播行为

    • 传播行为相关的常量,以PROPAGATION开头。
    • 解决业务层方法之间的相互调用的问题。
    • web层-->业务层-->持久层
      假设持久层有两个dao,dao1,dao2。业务层有两个service,service1和service2。
    Dao1{
    xxx(){}
    }
    
    Dao2{
    yyy(){}
    }
    
    Service1{
        aaa(){
            dao1.xxx();
            dao2.yyy();
        }
    }
     
    Service2{
        bbb();
    }
    

    事务是加在业务层的。若此时业务复杂,需要调用service1和service2的方法来共同完成业务功能。而此时service1和service2都有自己的事务管理,那么事务到底使用service1里的还是service2里的呢?此时就用到了业务的传播行为。

    事务的传播行为 说明
    PROPAGATION_REQUIRED 支持当前事务,如果不存在,就新建一个。
    PROPAGATION_SUPPORTS 支持当前事务,如果不存在,就不使用事务。
    PROPAGTION_MANDATORY 支持当前事务,如果不存在,就抛出异常。
    PROPAGATION_REQUIRES_NEW 如果有事务存在,挂起当前事务,创建 一个新的事务。
    PROPAGATION_NOT_SUPPORTED 如果有事务存在,挂起当前事务。以非事务的方式进行。
    PROPAGATION_NEVER 如果有事务存在,抛出异常。以非事务的方式进行。
    PROPAGATION_NESTED 如果有事务存在,则嵌套事务执行。
    • 重点记忆这三种:PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW,PROPAGATION_NESTED。
      • PROPAGATION_REQUIRED:保证service1的aaa()和service2的bbb()同一个事务里。
      • PROPAGATION_REQUIRES_NEW:保证service1的aaa()和service2的bbb()不在同一个事务里。
      • PROPAGATION_NESTED:service1的aaa()执行完后可以设置一个保存点,如果service2的bbb()执行时出了问题,可以选择回滚到保存点,也可以选择回滚到最初点。是一种嵌套事务。

    TransactionStatus

    提供一组方法来获取、设置事务的一些状态信息。比如isCompleted(),isRollBackOnly()。

    三个接口直接的关系

    Spring中DepaltformTransactionManager根据TransactionDefinition中设置的事务隔离级别和传播行为,来管理事务,将信息保存到TransactionStatus中。

    Spring的编程式事务管理

    需手动编写代码,在需要用到事务的方法中编写代码(一般不使用)

    1. 配置事务管理器platformTransactionManager。
      对于jdbc 需要datasourceTransactionManager 其中必须定义数据源属性dataSource,jdbc中是c3p0的连接池
    2. 事务管理的模板(注意和sql模板不同) transactionTemplate 事务管理模板,其属性就是上面对应的事务管理器。
    3. 在需要事务管理的代码处使用内部匿名类来执行运行sql的代码,这样将所有的操作后台的sql都会放在同一个事务中。

    Spring的声明式事务管理

    1. 首先还是要配置事务管理器
    2. 配置事务管理具体方法

    经典ProxyFactoryBean(使用动态代理的技术,用法已经渐渐废弃)

    需要配置TransactionProxyFactoryBean 属性包括target(标注哪个Bean需要事务管理) 和 事务管理器(上面配置的),在bean的配置中通过property来配置事务的传播行为和隔离级别。(只能对一个目标进行配置,就是那个target,不好用)

    使用aop来进行事务管理

    使用基于AspectJ的Spring AOP来管理

    xml配置

    配置通知 <tx:advice>
    配置切面 <aop:aspect>,在切面中配置通知和切点。

    注解配置

    @Transactional即可配置;对需要的类配置,同时也可配置相关的隔离级别和传播行为属性。

    参考文章
    http://www.cnblogs.com/lyh421/p/6726319.html

    相关文章

      网友评论

          本文标题:Spring事务管理入门

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