spring--声明式事务(包含基于注解和基于xml文件的配置方式)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring--声明式事务(包含基于注解和基于xml文件的配置方式)相关的知识,希望对你有一定的参考价值。

一.基于注解

步骤如下:

  1. 引入jar(mysql驱动,c3p0数据源,spring的必要jar)
  2. applicationContext.xml的配置
  3. Service和Dao的类上都加上对应的注解使其在ioc容器中,service的方法上面加上注解@Transactional

applicationContext.xml的配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    
    <context:component-scan base-package="com.transaction.demo"></context:component-scan>
    
    <!-- 导入资源文件 -->
    <context:property-placeholder location="classpath:db.properties"/>
    
    <!-- 配置 C3P0 数据源 -->
    <bean id="dataSource"
        class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
        <property name="driverClass" value="${jdbc.driverClass}"></property>

        <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
    </bean>
    
    <!-- 配置 Spirng 的 JdbcTemplate -->
    <bean id="jdbcTemplate" 
        class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <!-- 配置事务管理器 -->
    <bean id="transactionManager" 
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <!-- 启用事务注解 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
    
</beans>

编程式事务和声明式事务:

  • 编程式事务管理: 将事务管理代码嵌入到业务方法中来控制事务的提交和回滚. 在编程式管理事务时, 必须在每个事务操作中包含额外的事务管理代码.
  • 声明式事务管理: 大多数情况下比编程式事务管理更好用. 它将事务管理代码从业务方法中分离出来, 以声明的方式来实现事务管理. 事务管理作为一种横切关注点, 可以通过 AOP 方法模块化. Spring 通过 Spring AOP 框架支持声明式事务管理.

事务的传播行为:

技术分享

 利用的场景介绍:

假如用户需要购买一本书号为isbn的书,需要做以下几件事情,这一系列的事情都必须放在一个事务里面,买一本书的事务,我们称之为事务A

(根据isbn检查这本书的库存是否足够,如果不够的话,向外抛出异常,

检查用户余额是否足额,如果不够的话,向外抛出异常,

如果没有异常,则更新库存,从用户的银行卡扣钱)

假如用户在一个订单里面除了买了书a,还买了书c,书d,买这三本书是一个订单也在一个事务里面,我们称之为事务B

假如用户的余额只够买书a,还书b,那么运行结果是什么呢?

前两本成功,后一本失败呢?

三本书的购买均以失败告终?

这个时候,就取决于事务A上被设置的传播属性propagation,

三本书的购买都失败的场合 ⇒ REQUIRED,propagation的默认值也是REQUIRED,则启用调用方法的事务,也就是事务B的事务,挂起自己本身的事务A

前两本成功的场合  ⇒   propagation是REQUIRES_NEW的时候,则将调用方法的事务挂起,也就是事务B的事务被挂起,启用自己本身的事务

@Transactional的其他属性介绍:

    1. 使用 isolation 指定事务的隔离级别, 最常用的取值为 READ_COMMITTED
    2. 通常情况下spring的声明式事务对多有的运行时异常进行回滚,也可以通过属性(rollbackFor,rollbackForClassName,noRollbackFor,noRollbackForClassName)来进行设置
    3. 使用readOnly指定事务为只读,这样帮助数据库引擎优化事务
    4. timeout指定强制回滚之前事务可以占用的时间

二.基于XML文件配置

步骤如下:

  1. 引入jar(mysql驱动,c3p0数据源,spring的必要jar)
  2. applicationContext-xml.xml的配置
  3. Service和Dao的类和方法上所有的注解去掉

applicationContext-xml.xml的配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    
    <context:component-scan base-package="com.transaction.demo.xml"></context:component-scan>
    
    <!-- 导入资源文件 -->
    <context:property-placeholder location="classpath:db.properties"/>
    
    <!-- 配置 C3P0 数据源 -->
    <bean id="dataSource"
        class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
        <property name="driverClass" value="${jdbc.driverClass}"></property>

        <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
    </bean>
    
    <!-- 配置 Spirng 的 JdbcTemplate -->
    <bean id="jdbcTemplate" 
        class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <!-- 配置 dao/service bean (此处的配置省略) -->
    
    
    <!-- 1. 配置事务管理器 -->
    <bean id="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="purchase" propagation="REQUIRES_NEW"/>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
    
    <!-- 3. 配置事务切入点, 以及把事务切入点和事务属性关联起来 -->
    <aop:config>
        <aop:pointcut expression="execution(* com.transaction.demo.xml.tx.service.*.*(..))" 
            id="txPointCut"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>    
    </aop:config>
    
</beans>

 

以上是关于spring--声明式事务(包含基于注解和基于xml文件的配置方式)的主要内容,如果未能解决你的问题,请参考以下文章

Spring声明式事务管理(基于注解方式实现)

spring事物配置,声明式事务管理和基于@Transactional注解的使用

spring事物配置,声明式事务管理和基于@Transactional注解的使用

spring事物配置,声明式事务管理和基于@Transactional注解的使用

spring基于注解的声明式事务控制

阶段3 2.Spring_10.Spring中事务控制_7 spring基于注解的声明式事务控制