Spring事务

引用:Spring 中常用的两种事务配置方式以及事务的传播性、隔离级别

  • 事务的属性

  • 原子性

事务有一个原子组成,确保动作要么都完成,要么都不完成

  • 一致性

事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态
A给B转钱,无论怎么转,A和B的钱的总数都是一致的

  • 隔离性

多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰

  • 持久性

指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的

Spring的事务分为声明式编程式两种

  • 编程式事务 是在代码中加入处理事务的逻辑,在代码中显式的调用beginTransaction(),commit(),rollback()等

  • 声明式事务 建立在AOP上,本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完看情况进行回滚或者提交

区别:
声明式事务不需要在业务逻辑代码中惨杂事务管理的代码,做到了非侵入式的开发,但是不足的是编程式事务可以作用到代码块的级别,而声明式事务只能作用到方法

声明式事务又分为基于配置的和基于@Transactional注解

  • 基于配置

配置事务管理器

<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">       
          <property name="dataSource" ref="dataSource"></property>  
</bean>

配置需要加入事务的规则

<!-- 定义事务管理器 -->  
    <bean id="transactionManager"  
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
        <property name="dataSource" ref="dataSource" />  
    </bean>  
    <!-- 下面使用aop切面的方式来实现 -->  
    <tx:advice id="TestAdvice" transaction-manager="transactionManager">  
        <!--配置事务传播性,隔离级别以及超时回滚等问题 -->  
        <tx:attributes>  
            <tx:method name="save*" propagation="REQUIRED" />  
            <tx:method name="del*" propagation="REQUIRED" />  
            <tx:method name="update*" propagation="REQUIRED" />  
            <tx:method name="add*" propagation="REQUIRED" />  
            <tx:method name="*" rollback-for="Exception" />  
        </tx:attributes>  
    </tx:advice>  
    <aop:config>  
        <!--配置事务切点 -->  
        <aop:pointcut id="services"  
            expression="execution(* com.website.service.*.*(..))" />  
        <aop:advisor pointcut-ref="services" advice-ref="TestAdvice" />  
    </aop:config>  
  • 基于@Transactional注解

配置事务管理器

<!-- 定义事务管理器 -->    
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">    
    <property name="dataSource" ref="dataSource" />    
</bean>    
<!--使用注释事务 -->    
<tx:annotation-driven  transaction-manager="transactionManager" />

在需要加入事务的方法或者类上添加@Transactional

PS:annotation-driven 这样的注解,其含义就是支持注解

  • @Transactional 注解应该只被应用到 public 可见度的方法上。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错, 但是这个被注解的方法将不会展示已配置的事务设置

  • @Transactional 注解可以被应用于接口定义和接口方法、类定义和类的 public 方法上。然而,请注意仅仅 @Transactional 注解的出现不足于开启事务行为,它仅仅 是一种元数据,能够被可以识别 @Transactional 注解和上述的配置适当的具有事务行为的beans所使用。上面的例子中,其实正是 <tx:annotation-driven/>元素的出现 开启 了事务行为

  • Spring事务7个传播级别

@Transactional(propagation=Propagation.REQUIRED)

定义在存在多个事务同时存在的时候,Spring应该如何处理这些事务的行为。这些属性在TransactionDefinition中定义

  1. PROPAGATION_REQUIRED:

支持当前事务,如果当前没有事务,就新建一个事务(默认)

  1. PROPAGATION_REQUIRES_NEW:

新建事务,如果当前存在事务,把当前事务挂起。新建的事务将和被挂起的事务没有任何关系,是两个独立的事务

  1. PROPAGATION_SUPPORTS:

支持当前事务,如果当前没有事务,就以非事务方式执行

  1. PROPAGATION_MANDATORY:

支持当前事务,如果当前没有事务,就抛出异常

  1. PROPAGATION_NOT_SUPPORTED:

以非事务方式执行操作,如果当前存在事务,就把当前事务挂起

  1. PROPAGATION_NEVER:

以非事务方式执行,如果当前存在事务,则抛出异常

  1. PROPAGATION_NESTED(没明白):

如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行

  • Spring事务5个隔离级别

@Transactional(isolation = Isolation.READ_UNCOMMITTED)
  1. ISOLATION_DEFAULT:

这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.

  1. ISOLATION_READ_UNCOMMITTED:

这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。
这种隔离级别会产生脏读,不可重复读和幻像读

  1. ISOLATION_READ_COMMITTED:

保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据

  1. ISOLATION_REPEATABLE_READ:

这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。
它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。

  1. ISOLATION_SERIALIZABLE :

这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。
除了防止脏读,不可重复读外,还避免了幻像读。

脏读:事务A对数据进行增删改,但是并未提交,在这时事务B获取了未提交的数据,然后事务A回滚,此时事务B就读到了脏数据
不可重复读:事务A读取了两次数据,在读取的两次中间,事务B修改了数据,导致事务A读取的两次结果不一样
幻读:事务A对一定范围的数据批量修改,此时事务B在范围内插入了一条新数据,则事务A失去了对新增数据的修改,用户发现表中还有没有修改的数据行,就好象发生了幻觉一样

  • Spring事务 只读

@Transactional(readOnly=true)
  • Spring事务 超时

@Transactional(timeout=30)
  • Spring事务 回滚

指定单一异常类:@Transactional(rollbackFor=RuntimeException.class)
指定多个异常类:@Transactional(rollbackFor={RuntimeException.class, Exception.class})
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。