• Spring (5)—声明式事务控制


    目录

    一、编程时事务控制相关对象

    1.1 PlatformTransactionManager

    1.2 TransactionDefinition

    1.2.1 事务隔离级别

    1.2.2 事务传播行为

    1.3 TransactionStatus

    二、基于XML的声明式事务控制

    2.1 什么是声明式事务控制

    2.2 声明式事务控制的实现

    2.3 切点方法的事务参数的配置

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

    3.1 使用注解配置声明式事务控制

    3.2 注解配置声明式事务控制解析

    3.3 知识要点


    一、编程时事务控制相关对象

    1.1 PlatformTransactionManager

    PlatformTransactionManager接口是Spring 的事务管理器,里面提供了我们常用的操作事务的方法

    方法说明

    TransactionStatus  getTransaction

    (TransactionDefination defination)

    获取事务的状态信息
    void  commit(TransactionStatus status)提交事务
    void  rollback(TransactionStatus status)回滚事务

    注意:

    PlatformTransactionManager 是接口类型,不同的 Dao 层技术则有不同的实现类,例如:Dao 层技术是jdbc 或 mybatis 时:org.springframework.jdbc.datasource.DataSourceTransactionManager

    Dao 层技术是hibernate时:org.springframework.orm.hibernate5.HibernateTransactionManager

    1.2 TransactionDefinition

    TransactionDefinition 是事务的定义信息对象,里面有如下方法:

    方法说明
    int  getIsolationLevel()获得事务的隔离级别
    int  getPropogationBehavior()获得事务的传播行为
    int  getTimeout()获得超时时间
    boolean  isReadOnly()是否只读

    1.2.1 事务隔离级别

    设置隔离级别,可以解决事务并发产生的问题,如脏读、不可重复读和虚读。

    • ISOLATION_DEFAULT
    • ISOLATION_READ_UNCOMMITTED
    • ISOLATION_READ_COMMITTED
    • ISOLATION_REPEATABLE_READ
    • ISOLATION_SERIALIZABLE

    1.2.2 事务传播行为

    • REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。一般的选择(默认值)
    • SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行(没有事务)
    • MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常
    • REQUERS_NEW:新建事务,如果当前在事务中,把当前事务挂起。
    • NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
    • NEVER:以非事务方式运行,如果当前存在事务,抛出异常
    • NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行 REQUIRED 类似的操作
    • 超时时间:默认值是-1,没有超时限制。如果有,以秒为单位进行设置
    • 是否只读:建议查询时设置为只读

    1.3 TransactionStatus

    方法说明
    boolean  hasSavepoint()是否存储回滚点
    boolean  isCompleted()事务是否完成
    boolean  isNewTransaction()是否是新事务
    boolean  isRollbackOnly()事务是否回滚

    二、基于XML的声明式事务控制

    2.1 什么是声明式事务控制

    SPring的声明式事务顾名思义就是采用声明的方式来处理事务。这里所说的声明,就是指在配置文件中声明,用在Spring配置文件中声明式的事务处理来代替代码是的处理事务

    声明式事务处理的作用

    • 事务管理不入侵开发的组件。具体来说,业务逻辑对象就不会意识到正在事务管理之中,事实上也应该如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要改变事务管理策划的话,也只需要在定义文件中重新配置即可
    • 在不需要事务管理的时候,只要在设定文件上修改一下,即可移去事务管理服务,无需改变代码重新编译 ,这样维护起来极其方便

    注意:Spring 声明式事务控制底层就是AOP

    2.2 声明式事务控制的实现

    ① 引入tx命名空间

    1. <beans xmlns="http://www.springframework.org/schema/beans"
    2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xmlns:aop="http://www.springframework.org/schema/aop"
    4. xmlns:tx="http://www.springframework.org/schema/tx"
    5. xsi:schemaLocation="
    6. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    7. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
    8. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
    9. ">

    ② 配置事务增强

    1. <bean id="accountService" class="com.learn.service.impl.AccountServiceImpl">
    2. <property name="accountDao" ref="accountDao"/>
    3. bean>
    4. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    5. <property name="dataSource" ref="dataSource"/>
    6. bean>
    7. <tx:advice id="txAdvice" transaction-manager="transactionManager">
    8. <tx:attributes>
    9. <tx:method name="*"/>
    10. tx:attributes>
    11. tx:advice>

    ③ 配置事务 AOP 织入

    1. <aop:config>
    2. <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.learn.service.impl.*.*(..))"/>
    3. aop:config>

    ④ 测试事务控制转账业务代码

    1. public void transfer(String outMan, String inMan, double money) {
    2. accountDao.out(outMan,money);
    3. int i = 1/0;
    4. accountDao.in(inMan,money);
    5. }

    2.3 切点方法的事务参数的配置

    1. <tx:advice id="txAdvice" transaction-manager="transactionManager">
    2. <tx:attributes>
    3. <tx:method name="*"/>
    4. tx:attributes>
    5. tx:advice>

    其中, 代表切点方法的事务参数的配置,例如:

    : method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" timeout="-1" read-only="false"/>

    • name:切点方法名称
    • isolation:事务的隔离级别
    • propogation:事务的传播行为
    • timeout:超时时间
    • read-only:是否只读

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

    3.1 使用注解配置声明式事务控制

    1. 编写 AccoutDao

    1. @Repository("accountDao")
    2. public class AccountDaoImpl implements AccountDao {
    3. @Autowired
    4. private JdbcTemplate jdbcTemplate;
    5. public void out(String outMan, double money) {
    6. jdbcTemplate.update("update account set money=money-? where name=?",money,outMan);
    7. }
    8. public void in(String inMan, double money) {
    9. jdbcTemplate.update("update account set money=money+? where name=?",money,inMan);
    10. }
    11. }

    2. 编写 AccoutService

    1. @Service("accountService")
    2. @Transactional(isolation = Isolation.REPEATABLE_READ)
    3. public class AccountServiceImpl implements AccountService {
    4. @Autowired
    5. private AccountDao accountDao;
    6. @Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
    7. public void transfer(String outMan, String inMan, double money) {
    8. accountDao.out(outMan,money);
    9. int i = 1/0;
    10. accountDao.in(inMan,money);
    11. }
    12. }

    3. 编写 applicationContext.xml 配置文件

    1. <context:component-scan base-package="com.anno"/>
    2. <tx:annotation-driven transaction-manager="transactionManager"/>
    3. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    4. <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    5. <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"/>
    6. <property name="user" value="root"/>
    7. <property name="password" value="root"/>
    8. bean>
    9. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    10. <property name="dataSource" ref="dataSource"/>
    11. bean>
    12. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    13. <property name="dataSource" ref="dataSource"/>
    14. bean>

    3.2 注解配置声明式事务控制解析

    ① 使用 @Transactional 在需要进行事务控制的类或是方法上修饰,注解可用的属性同 xml 配置方式,例如隔离 级别、传播行为等。

    ② 注解使用在类上,那么该类下的所有方法都使用同一套注解参数配置。

    ③ 使用在方法上,不同的方法可以采用不同的事务参数配置。

    ④ Xml配置文件中要开启事务的注解驱动: annotation-driven/>

    3.3 知识要点

  • 相关阅读:
    达芬奇机器人手术模拟系统RobotixMentQr
    产品经理应该学习墨刀还是Axure?
    [Vue 代码模板] Vue3 中使用 Tailwind CSS + NutUI 实现侧边工具栏切换主题
    基于SSH开发个人博客系统(论坛系统)
    【调度算法】NSGA II
    C++ [继承]
    C++继承
    AWS SSA-C003 #21
    数据结构与算法——18.avl树
    todo-list案例--全局事件总线
  • 原文地址:https://blog.csdn.net/weixin_61843013/article/details/126055569