Spring事务管理详解及案例(实现)

在研究Spring事务管理之前,我们首先应该了解什么是事务。大家可以看看我的另外一篇博客:java JDBC事务和JTA事务详解;这里就不做介绍了。

Spring事务管理

Spring事务管理的核心接口是PlatformTransactionManager --->也是最底层的实现方式;

Spring事务的传播属性

由上图可知,Spring定义了7个以PROPAGATION_开头的常量表示它的传播属性。

名称 解释
PROPAGATION_REQUIRED 0 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择,也是Spring默认的事务的传播。
PROPAGATION_SUPPORTS 1 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY 2 支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW 3 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED 4 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER 5 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED 6 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

Spring事务的隔离级别

名称 解释
ISOLATION_DEFAULT -1 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与JDBC的隔离级别相对应
ISOLATION_READ_UNCOMMITTED 1 这是事务最低的隔离级别,它充许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻读。
ISOLATION_READ_COMMITTED 2 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。
ISOLATION_REPEATABLE_READ 4 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻读。
ISOLATION_SERIALIZABLE 8 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻读。

调用PlatformTransactionManager接口的getTransaction()的方法得到的是TransactionStatus接口的一个实现 

配置事务管理器

介绍完Spring事务的管理的流程后。接下来可以动手试试Spring是如何配置事务管理器的 

注:我这里用的是hibernate4做的事务实现

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="mappingLocations">
        <list>
            <value>classpath:/com/jspgou/core/entity/hbm/*.hbm.xml</value>
            <value>classpath:/com/jspgou/cms/entity/hbm/*.hbm.xml</value>
        </list>
    </property>
    <property name="packagesToScan">
        <list>
            <value>com.ifunpay.portal.entity</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <value>
            hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
            hibernate.show_sql=${jdbc.showSql:false}
            hibernate.format_sql=false
            hibernate.query.substitutions=true 1, false 0
            hibernate.jdbc.batch_size=20
            hibernate.cache.use_query_cache=${jdbc.use_query_cache:false}
            hibernate.cache.use_second_level_cache=${jdbc.use_second_level_cache:false}
            hibernate.cache.region.factory_class=org.hibernate.cache.redis.SingletonRedisRegionFactory
            hibernate.cache.provider_configuration_file_resource_path=/settings.properties
        </value>
    </property>
    <property name="entityInterceptor">
        <bean class="com.jspgou.common.hibernate3.TreeIntercptor"/>
    </property>
</bean>

<!-- jdbcTemplate -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
</bean>


<!-- 事务配置 -->
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

或者使用mybatis的时候利用Spring做事务管理----说白了就是jdbc事务,因为mybatis没有像hibernate一样有自己的一套实现事务的方式。

<bean id="slave" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc_slave.url}"/>
    <property name="username" value="${jdbc_slave.username}"/>
    <property name="password" value="${jdbc_slave.password}"/>
    <!--配置监控统计拦截的filters,去掉后监控界面sql无法统计 -->
    <property name="filters" value="stat"/>
    <!--maxActive: 最大连接数量 -->
    <property name="maxActive" value="${cpool_slave.maxPoolSize:100}"/>
    <!--maxActive: 最小连接池数量 -->
    <property name="minIdle" value="${cpool_slave.minPoolSize:1}"/>
    <!--initialSize: 初始化连接 -->
    <property name="initialSize" value="${cpool.initialPoolSize:20}"/>
    <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
    <property name="timeBetweenEvictionRunsMillis" value="${cpool.checkoutTimeout:6000}"/>
</bean>
<!-- 配置多数据源映射关系 -->
<bean id="dataSource" class="com.ifunpay.portal.ds.DynamicDataSource">
    <property name="targetDataSources">
        <map key-type="java.lang.String">
            <entry key="master" value-ref="master"></entry>
            <entry key="slave" value-ref="slave"></entry>
        </map>
    </property>
    <property name="defaultTargetDataSource" ref="master"/>
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

配置了事务管理器后,事务当然还是得我们自己去操作,Spring提供了两种事务管理的方式:编程式事务管理和声明式事务管理,让我们分别看看它们是怎么做的吧。

编程式事务管理

编程式事务管理我们可以通过PlatformTransactionManager实现来进行事务管理,同样的Spring也为我们提供了模板类TransactionTemplate进行事务管理,下面主要介绍模板类,我们需要在配置文件中配置

<!--配置事务管理的模板-->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
    <property name="transactionManager" ref="transactionManager"></property>
    <!--定义事务隔离级别,-1表示使用数据库默认级别-->
    <property name="isolationLevelName" value="ISOLATION_DEFAULT"></property>
    <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"></property>
</bean>



猜你喜欢

转载自blog.csdn.net/qq_19167629/article/details/80409226