• Spring 事务管理


    0.前言

    这是我看完书,敲完demo,做的一篇笔记.
    如果有朋友恰巧看到这篇文章,请先跟着资料敲一遍再看会比较好理解.

    1.事务管理相关接口

    Spring-tx 是Spring提供事务管理功能的依赖包.在它的org.Springframework.transaction包下有三个接口文件:PlatformTransactionManager,TransactionDefinition和TransactionStatus.

    PlatformTransactionManager

    这是 Spring 声明式事务基础结构中的中心接口。功能和名字一样,是平台事务管理器,提供了三个方法:

    • commit(TransactionStatus status):Commit the given transaction, with regard to its status. 提交事务
    • TransactionStatus getTransaction(TransactionDefinition definition):Return a currently active transaction or create a new one, according to the specified propagation behavior. 获取事务状态
    • rollback(TransactionStatus status):Perform a rollback of the given transaction. 事务回滚

    然后,这个接口有三个实现类

    • org.springframework.jdbc.datasource.DataSourceTransactionManager 配置JDBC数据源的事务管理器
    • org.springframework.orm.Hibernate4.HibernateTransationManager Hibernate的事务管理器
    • org.springframework.transaction.jta.JtaTransactionManager 全局事务管理器

    TransactionDefinition

    TransactionDefinition 接口是事务定义的对象,该对象中定义了事务规则,并提供了获取事务相关信息的方法.
    它声明了以下方法:

    • string getName():获取事务对象名称
    • int getlsolationLevel():获取事务的隔离级别
    • int getPropagationBehavior():获取事务的传播行为
    • int setTimeout:设置事务的超时时间
    • boolean isReadOnly():获取事务是否只读

    其中最重要的是它的传播行为还有隔离级别,有下列常量可选

    TransactionStatus

    TransactionStatus 接口是事务的状态,描述了某一时间点上事务的状态信息.
    包含以下方法:

    • void flush0:刷新事务
    • boolean isNewTransaction():获取是否是新事务
    • boolean isCompleted():获取事务是否完成
    • boolean isRollbackOnly():获取是否回滚
    • void setRollbackOnly():设置事务回滚

    2.事务管理方式

    事务管理可以通过编程实现,也可以通过声明事务(通过AOP技术)来管理.
    同样的,通过编程实现的事务管理,牵一发而动全身,所以现在大都采用声明式事务管理.
    然后,声明式事务管理同样可以再细分为xml和annotation两种实现方式.

    二者主要在于事务的声明和配置文件有所区别,所以以下内容主要就此展开.
    如果要看完整demo,可以访问这个链接SSM-bootstrap/MyTransaction at master · rpishgithub/SSM-bootstrap

    基于xml的声明式事务管理

    • 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:tx="http://www.springframework.org/schema/tx"  
     xmlns:aop="http://www.springframework.org/schema/aop"  
     xsi:schemaLocation="http://www.springframework.org/schema/beans  
     http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.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">  
    <!--    1.配置数据源-->  
     <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
            <property name="driverClassName" value="com.mysql.jdbc.Driver"/>  
            <property name="url" value="jdbc:mysql://localhost:3306/spring_db"/>  
            <property name="username" value="root"/>  
            <property name="password" value="pass"/>  
      
        </bean>  
          
    <!--    2.配置JDBC Templat-->  
     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
    <!-- 使用默认数据源-->  
     <property name="dataSource" ref="dataSource"/>  
        </bean>  
    <!--    3.定义Bean UserDaoImpl-->  
     <bean id="userDao" class="tech.rpish.dao.UserDaoImpl">  
    <!-- 将jdbcTemplate注入到userDao实例中(预留了一个setter)-->  
     <property name="jdbcTemplate" ref="jdbcTemplate"/>  
        </bean>  
          
    <!--    4.事务管理器,依赖数据源-->  
     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
            <property name="dataSource" ref="dataSource"/>  
        </bean>  
      
    <!--    XML-based Transaction-->  
    <!--    5.编写通知,对事务进行增强/通知,编写切入点及具体执行细节-->  
     <tx:advice id="txAdvice" transaction-manager="transactionManager">  
            <tx:attributes>  
                <tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/>  
            </tx:attributes>  
        </tx:advice>  
    <!--    6.编写aop-->  
     <aop:config>  
            <aop:pointcut id="txPointcut" expression="execution(* tech.rpish.dao.*.*(..))"/>  
            <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>  
        </aop:config>  
    </beans>
    

    基于annotation的声明式事务管理

    • 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:tx="http://www.springframework.org/schema/tx"  
     xmlns:aop="http://www.springframework.org/schema/aop"  
     xsi:schemaLocation="http://www.springframework.org/schema/beans  
     http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.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">  
    <!--    1.配置数据源-->  
     <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
            <property name="driverClassName" value="com.mysql.jdbc.Driver"/>  
            <property name="url" value="jdbc:mysql://localhost:3306/spring_db"/>  
            <property name="username" value="root"/>  
            <property name="password" value="pass"/>  
      
        </bean>  
          
    <!--    2.配置JDBC Templat-->  
     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
    <!-- 使用默认数据源-->  
     <property name="dataSource" ref="dataSource"/>  
        </bean>  
    <!--    3.定义Bean UserDaoImpl-->  
     <bean id="userDao" class="tech.rpish.dao.UserDaoImpl">  
    <!-- 将jdbcTemplate注入到userDao实例中(预留了一个setter)-->  
     <property name="jdbcTemplate" ref="jdbcTemplate"/>  
        </bean>  
          
    <!--    4.事务管理器,依赖数据源-->  
     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
            <property name="dataSource" ref="dataSource"/>  
        </bean>
    	    <tx:annotation-driven transaction-manager="transactionManager"/>  
    </beans>
    

    这样看可能不是很明显,丢进IDEA 的 Diff里对比一下就清楚了

    开头都是老四样

    1. 配置数据源(数据库)
    2. 配置JDBC Template,然后把数据源通过参数传给它
    3. 创建个bean,把UserDaoImpl类注册进来,通过参数把JDBC Template传给它(为什么要传给它呢?看代码就知道啦,我们的sql操作可都是通过JDBC Template来执行的,所以预留了一个Setter方法来注入)
    4. 新建个bean,注册事务管理器,配置数据源

    接着就不一样啦.
    xml先用<tx:advice>编写通知,然后再通过aop对切入点进行事务增强/通知.
    说着轻松,具体用到的各个标签,它们的关系还挺麻烦的.
    基于annotation就简单多了,一句话,annotation驱动,再赋个事务管理器.
    <tx:annotation-driven transaction-manager="transactionManager"/>
    然后到DaoImpl的类或者方法上加上@Transactional注解,然后和<tx:attributes>一样附上TransactionDefinition该有的参数就好了.

    遇到的问题

    然后我在写这个demo的时候也遇到了几个问题,如果有人遇到可以参考一下.

  • 相关阅读:
    路由器配置深入浅出—静态路由和缺省路由配置
    盘点飞思卡尔i.MX多媒体处理器前世今生 (转)
    ubuntu18.04下取消中键复制粘贴功能
    uboot常用命令及其使用
    MCU软件最佳实践——使用printf打印数据
    uboot无法通过nfs加载ubuntu18.04中的文件(转)
    GNU C字节对齐__attribute__((aligned(n))) #pragma pack(n)
    ENDIAN的由来及BIGEDIAN 和LITTLEENDIAN(转)
    自动生成c# Model属性
    使用JAVA生成随机的AES密钥
  • 原文地址:https://www.cnblogs.com/rpish/p/15244755.html
Copyright © 2020-2023  润新知