关于Spring事务的隔离级别,传播行为,及其管理配置

Spring支持两种类型的事务管理:

  • 编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。(不常用)
  • 声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。(常用)

基于XML的声明式事务管理:

<!--不是事务的包,他的作用是将Spring提供的事务通过切面的形式添加到代码中-->
	<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjweaver</artifactId>
	<version>1.9.9</version>
	</dependency>1)配置事务管理器
常见的事务管理器:JDBC事务管理器、Hibernate事务管理器、JTA分布式事务管理器
可以理解为增强类,在核心业务基础上增加的功能;
<!--SpringJDBC事务管理器添加到Spring容器中 -->
	<bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/>
	</bean>2)配置事务属性
<!--设置事务的属性-->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
	<tx:attributes>
<!--
	name:需要添加方法的方法名称,建议使用通配符表达式 *
	isolation:数据库的默认隔离级别,默认是 default
	propagation:事务的传播特性,默认:REQUIRED
	read-only:只读,针对查询操作
	rollback-for:默认情况下对RuntimeExceptionError进行回滚,主要解决的
	是自定义的异常。配置异常时需要写全限定名称(包名 + 类名)
	no-rollback-for:配置不需要回滚的异常
-->
	<tx:method name="add*" propagation="REQUIRED" isolation="DEFAULT"no-rollback-for="java.lang.ArithmeticException"/>
	<tx:method name="edit*" propagation="REQUIRES_NEW"isolation="DEFAULT"/>
	<tx:method name="del*" propagation="REQUIRED" isolation="DEFAULT"/>
	</tx:attributes>
	</tx:advice>3)配置事务切面
<!--配置事务的切面-->
	<aop:config>
	<!--切点表达式-->
		<aop:pointcut id="transactionPointCut" expression="execution(*com.soft.service.*.*(..))"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointCut"/>
	</aop:config>

注解方式的声明式事务管理:

只需要配置事务管理器与注解式事务管理,并且在要开启事务的方法上加上注解: @Transactional

<?xml version="1.0" encoding="UTF-8"?>
<beans  头信息省略。。。。。。
 
        <context:component-scan base-package="com.wanshi"/> <!--包扫描位置-->
 
        <context:property-placeholder location="classpath:db.properties"/>
 
        <!--一下信息皆是为mapper的映射文件实例化所做的操作-->
                <!--数据库信息-->
                <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
                        <property name="driverClassName" value="${driverClass}" />
                        <property name="url" value="${jdbcUrl}" /> <!--记得连接自己的数据库-->
                        <property name="username" value="${user}" />
                        <property name="password" value="${password}" />
                </bean>
 
                <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
                        <property name="dataSource" ref="dataSource"/>
                </bean>
 
                <!--sqlSessionFoctory工厂类,用于生产sqlsession对象-->
                <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
                        <property name="dataSource" ref="dataSource"/>
                        <!--绑定Mybatis的配置文件-->
                        <property name="configLocation" value="classpath:mybatis.xml"/>
                </bean>
                <!--配置dao接口扫描包,动态的实现了dao接口可以注入到Spring容器中-->
                <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
                        <!--注入sqlSessionFactory-->
                        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
                        <!--受扫描的dao包-->
                        <property name="basePackage" value="com.wanshi.dao"/>
                </bean>
                <!--将userService交由Spring管理,创建时注入userMapper参数-->
                <bean id="userService" class="com.wanshi.service.impl.userService_Impl" scope="singleton">
                        <property name="userMapper" ref="userMapper"/>
                </bean>
 
<!--        配置事务管理器-->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                <property name="dataSource" ref="dataSource"/>
        </bean>
 
<!--        注解式事务声明配置开关-->
        <tx:annotation-driven transaction-manager="transactionManager" />
 
</beans>

事务最重要的两个特性:

(事务是逻辑处理原子性的保证手段,通过使用事务控制,可以极大的避免出现逻辑处理失败导致的脏数据等问题。)

  • 事务的传播级别:定义了事务在 传播 方面的控制范围。

  • 数据的隔离级别:定义了事务在 数据库读写 方面的控制范围。

Spring的事务传播行为:

spring事务的传播行为说的是,当多个事务同时存在的时候,spring如何处理这些事务的行为。

  • PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就 加入该事务,该设置是最常用的设置。(Spring默认的传播行为)

  • PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不 存在事务,就以非事务执行。

  • PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前 不存在事务,就抛出异常。

  • PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。

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

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

  • PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则 按REQUIRED属性执行。

spring 的事务隔离:

spring 有五大隔离级别,默认值为 ISOLATION_DEFAULT(使用数据库的设置),其他四个隔离
级别和数据库的隔离级别一致:

  • ISOLATION_DEFAULT:用底层数据库的设置隔离级别,数据库设置的是什么我就用什么;
  • ISOLATION_READ_UNCOMMITTED:读未提交,最低隔离级别、事务未提交前,就可被其
    他事务读取(会出现幻读、脏读、不可重复读);
  • ISOLATION_READ_COMMITTED:读已提交,一个事务提交后才能被其他事务读取到(会造成
    幻读、不可重复读),SQL server 的默认级别;
  • ISOLATION_REPEATABLE_READ:可重复读,保证多次读取同一个数据时,其值都和事务开
    始时候的内容是一致,禁止读取到别的事务未提交的数据(会造成幻读),MySQL 的默认级
    别;
  • ISOLATION_SERIALIZABLE:序列化,代价最高最可靠的隔离级别,该隔离级别能防止脏
    读、不可重复读、幻读。

脏读 : 表示一个事务能够读取另一个事务中还未提交的数据,如果另一个事务回滚数据,则当前事务读取的就是错误的数据。

不可重复读: 是指在一个事务内,多次读同一数据。

幻读 : 指同一个事务内多次查询返回的结果集不一样。比如同一个事务 A 第一次查询时候有 n 条
记录,但是第二次同等条件下查询却有 n+1 条记录。发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据,同一个记录的数据内容被修改了,所有数据行的记录就变多或者变少了。

你可能感兴趣的:(Spring框架,spring,java,hibernate)