• JavaWeb学习:Spring的事务管理


    一、Spring的事务管理的API

      ①、PlatformTransactionManager:平台事务管理器    

      • 平台事务管理器:接口,是Spring用于管理事务的真正的对象。
        • DataSourceTransactionManager            :底层使用JDBC管理事务
        • HibernateTransactionManager                 :底层使用Hibernate管理事务

      ②、TransactionDefinition         :事务定义信息

        事务定义:用于定义事务的相关的信息,隔离级别、超时信息、传播行为、是否只读

      ③、TransactionStatus:事务的状态

        事务状态:用于记录在事务管理过程中,事务的状态的对象。

    二、事务管理的API的关系

      Spring进行事务管理的时候,首先平台事务管理器根据事务定义信息进行事务的管理,在事务管理过程中,产生各种状态,将这些状态的信息记录到事务状态的对象中。

    三、Spring的事务的传播行为

      Spring中提供了七中事务的传播行为      

    public void 方法A(){
      xxDao.save();
      yyDao.update();        
    }
    
    public void 方法b(){
      方法A();
      zzDao.del();
      ttDao.update();        
    }
      • 保证多个操作在同一个事务中
        • PROPAGATION_REQUIRED:默认值,如果方法A中有事务,使用方法A中的事务,如果没有事务,创建一个新事务。
        • PROPAGATION_SUPPORTS:支持事务,如果方法A中有事务,使用方法A中的事务。如果没有,不使用事务
        • PROPAGATION_MANDATORY:如果方法A中有事务,使用方法A中的事务,如果没有,抛出异常
      • 保证多个操作不在同一个事务中

        • PROPAGATION_REQUIRES_NEW:如果方法A中有事务,将事务挂起,创建新事务,只包含自身操作。如果方法A中没有事务,创建新事务,包含自身操作。
        • PROPAGATION_NOT_SUPPORTED:如果方法A中有事务,将事务挂起。不使用事务管理
        • PROPAGATION_NEVER:如果方法A中有事务,抛出异常
      • 嵌套式事务
        • PROPAGATION_NESTED:如果方法A中有事务,按照A的事务执行,执行完成后,设置一个保存点,执行方法B中的操作,如果没有异常,执行通过,如果有异常,选择回滚到最初位置或回滚到保存点。

    四、Spring的事务管理

      ①、搭建Spring的事务管理的环境

        Ⅰ、创建Service的接口和实现类

    public class AccountServiceImpl implements AccountService {
    
        private AccountDao accountDao;
    
        public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
        }
    
        @Override
        public void transfer(String from, String to, BigDecimal money) {
        accountDao.outMoney(from, money);
        accountDao.inMoney(to, money);
        }
    
    }

        Ⅱ、创建DAO的接口和实现类

    public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
    
        @Override
        public void outMoney(String from, BigDecimal money) {
        this.getJdbcTemplate().update("update account set money=money - ? where name = ?", money, from);
        }
    
        @Override
        public void inMoney(String to, BigDecimal money) {
        this.getJdbcTemplate().update("update account set money=money + ? where name = ?", money, to);
        }
    
    }

        Ⅲ、配置Service和DAO交给Spring管理

        <bean id="accountService" class="com.xxx.spring.transaction.demo1.AccountServiceImpl">
            <property name="accountDao" ref="accountDao"></property>
        </bean>
    
        <bean id="accountDao" class="com.xxx.spring.transaction.demo1.AccountDaoImpl">
            
        </bean>

        Ⅳ、配置连接池

        <context:property-placeholder location="classpath:jdbc.properties" />
    
        <bean id="dataSource"
            class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="driverClass" value="${jdbc.driverClass}" />
            <property name="jdbcUrl" value="${jdbc.url}" />
            <property name="user" value="${jdbc.username}" />
            <property name="password" value="${jdbc.password}" />
        </bean>

        Ⅴ、在DAO注入Jdbc的模板(注入的是dataSource的原因extends JdbcDaoSupport ,查看JdbcDaoSupport 的代码有setDataSource方法)

        <bean id="accountDao" class="com.xxx.spring.transaction.demo1.AccountDaoImpl">
            <property name="dataSource" ref="dataSource"></property>
        </bean>

        Ⅵ、编写测试方法

    @SpringJUnitConfig(locations = "classpath:tx.xml")
    public class SpringTxDemo {
        @Autowired
        private AccountService accountService;
    
        @Test
        public void demo1() {
        accountService.transfer("zhangsan", "lisi", new BigDecimal(1000.00));
        }
    }

    五、Spring的事务管理

      ①、一类:编程式事务(需要手动编写代码)

        Ⅰ、配置平台事务管理器

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

        Ⅱ、Spring提供了事务管理的模板类

        <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
            <property name="transactionManager" class="transactionManager"/>
        </bean>

        Ⅲ、业务层(Service)需要使用事务,将书屋管理模板类注入到业务层

        <bean id="accountService" class="com.xxx.spring.transaction.demo1.AccountServiceImpl">
            <property name="accountDao" ref="accountDao"></property>
            <!-- 注入事务管理的模板类 -->
            <property name="transactionTemplate" ref="transactionTemplate"/>
        </bean>

      ②、二类:声明式事务管理(通过配置实现)---底层原理:AOP(面向切面)

        在方法上通过增强的方式添加事务处理,此事务增强是环绕通知和异常抛出通知,不需要手动编写了,只需要配置就可以了

        Ⅰ、XML方式的声明式事务管理

          1、引入aop的开发包

          2、配置事务管理器

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

          3、配置增强

        <!-- 事务的增强 -->
        <tx:advice id="txadvice" transaction-manager="transactionManager">
            <tx:attributes>
                <!-- 事务规则 -->
                <!-- <tx:method name="save*" propagation="REQUIRED" />
                <tx:method name="update*" propagation="REQUIRED" />
                <tx:method name="delete*" propagation="REQUIRED" />
                <tx:method name="find" read-only="true" /> -->
                <tx:method name="*" propagation="REQUIRED" />
            </tx:attributes>
        </tx:advice>

    在使用<tx:advice...>需要添加约束

    <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:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context 
            https://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/aop 
            https://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/tx 
            http://www.springframework.org/schema/tx/spring-tx.xsd">

          4、AOP的配置

        <!-- Aop的配置 -->
        <aop:config>
            <!-- 配置切入点 -->
            <aop:pointcut expression="execution(* com.xxx.spring.transaction.demo1.AccountServiceImpl.*(..))" id="pointcut1"/>
            <!-- 配置单一切面 -->
            <aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"/>
            <!-- 配置切面  ref="aspectXML" 指定切面类-->
            <!-- <aop:aspect ref="aspectXML">
                前置通知
                <aop:before method="checkPri" pointcut-ref="product_save" />
                后置通知
                <aop:after-returning method="writeLog" pointcut-ref="product_delete" returning="result"/>
                环绕通知
                <aop:around method="checkPerformance" pointcut-ref="product_update"/>
                异常通知
                <aop:after-throwing method="afterThrowing" pointcut-ref="product_find" throwing="ex"/>
                最终通知
                <aop:after method="after" pointcut-ref="product_find"/>
            </aop:aspect> -->
        </aop:config>

        Ⅱ、注解方式的声明式事务管理

          1、引入aop的开发包

          2、配置事务管理器

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

          3、开启注解事务

        <tx:annotation-driven transaction-manager="transactionManager"/>

          4、在业务层添加注解

    @Transactional
    public class AccountServiceImpl implements AccountService {
    
        private AccountDao accountDao;
    
        public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
        }
        
        @Override
        public void transfer(String from, String to, BigDecimal money) {
    
        accountDao.outMoney(from, money);
        int d = 1 / 0;
        accountDao.inMoney(to, money);
        }
    }
  • 相关阅读:
    MyBatis学习记录02篇
    Mybatis学习记录01篇
    项目路径问题
    项目01-JavaWeb网上书城01之工具类
    面试篇01
    创建多线程的方式
    关于web.xml
    快捷键----快速生成未实现的方法
    自动化学习-Day03
    自动化学习-Day02
  • 原文地址:https://www.cnblogs.com/WarBlog/p/14134544.html
Copyright © 2020-2023  润新知