项目管理与SSM框架 Spring5(五)

简介: 项目管理与SSM框架 Spring5(五)

7.1 事务管理方案

在Spring框架中提供了两种事务管理方案:

  1. 编程式事务:通过编写代码实现事务管理。
  2. 声明式事务:基于AOP技术实现事务管理。

在Spring框架中,编程式事务管理很少使用,我们对声明式事务管理进行详细学习。

Spring的声明式事务管理在底层采用了AOP技术,其最大的优点在于无需通过编程的方式管理事务,只需要在配置文件中进行相关的规则声明,就可以将事务规则应用到业务逻辑中。

使用AOP技术为service方法添加如下通知:


7.2 事务管理器

Spring依赖事务管理器进行事务管理,事务管理器即一个通知类,我们为该通知类设置切点为service层方法即可完成事务自动管理。由于不同技术操作数据库,进行事务操作的方法不同。如:JDBC提交事务是connection.commit(),MyBatis提交事务是sqlSession.commit(),所以Spring提供了多个事务管理器。

事务管理器名称 作用
org.springframework.jdbc.datasource.DataSourceTransactionManager 针对JDBC技术提供的事务管理器。适用于JDBC和MyBatis。
org.springframework.orm.hibernate3.HibernateTransactionManager 针对于Hibernate框架提供的事务管理器。适用于Hibernate框架。
org.springframework.orm.jpa.JpaTransactionManager 针对于JPA技术提供的事务管理器。适用于JPA技术。
org.springframework.transaction.jta.JtaTransactionManager 跨越了多个事务管理源。适用在两个或者是多个不同的数据源中实现事务控制。

我们使用MyBatis操作数据库,接下来使用DataSourceTransactionManager进行事务管理。

1、引入依赖

<!-- 事务管理 -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-tx</artifactId>
  <version>5.3.13</version>
</dependency>
<!-- 事务底层 AspectJ -->
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.8.7</version>
</dependency>

2、配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context.xsd
     http://www.springframework.org/schema/aop
     http://www.springframework.org/schema/aop/spring-aop.xsd
     http://www.springframework.org/schema/tx
     http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!--扫描包-->
    <context:component-scan base-package="com.zj"/>
    <!--读取数据源配置文件-->
    <context:property-placeholder location="classpath:db.properties"/>
    <!--配置数据源-->
    <bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <!--创建Spring封装过的SqlSessionFactory对象-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="datasource"/>
    </bean>
    <!--创建Spring封装的SqlSession-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
    <!-- 该对象可以自动扫描持久层接口,并为接口创建代理对象 -->
    <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 配置扫描的接口包 -->
        <property name="basePackage" value="com.zj.dao"/>
    </bean>
     <!--事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="datasource"/>
    </bean>
    <!--事务相关配置-->
    <tx:advice id="txAdvice">
        <!--暂时都用默认配置-->
        <tx:attributes>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
    <!--配置切面(切点+通知)-->
    <aop:config>
        <!--切点-->
        <aop:pointcut id="point" expression="execution(* com.zj.service.*(..))"/>
        <!--通知-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="point"/>
    </aop:config>
</beans>

3、再次测试

账户 没变说明事务管理是成功的。


7.3 事务控制的API

Spring进行事务控制的功能是由三个接口提供的,这三个接口是Spring实现的,在开发中我们很少使用到,只需要了解他们的作用即可:

PlatformTransactionManager接口

PlatformTransactionManager是Spring提供的事务管理器接口,所有事务管理器都实现了该接口。该接口中提供了三个事务操作方法:

  • TransactionStatus getTransaction(TransactionDefinition definition):获取事务状态信息。
  • void commit(TransactionStatus status):事务提交
  • void rollback(TransactionStatus status):事务回滚

TransactionDefinition接口

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

  • String getName():获取事务对象名称。
  • int getIsolationLevel():获取事务的隔离级别。
  • int getPropagationBehavior():获取事务的传播行为。
  • int getTimeout():获取事务的超时时间。
  • boolean isReadOnly():获取事务是否只读。

TransactionStatus接口

TransactionStatus是事务的状态接口,它描述了某一时间点上事务的状态信息。它有如下方法:

  • void flush() 刷新事务
  • boolean hasSavepoint() 获取是否存在保存点
  • boolean isCompleted() 获取事务是否完成
  • boolean isNewTransaction() 获取是否是新事务
  • boolean isRollbackOnly() 获取是否回滚
  • void setRollbackOnly() 设置事务回滚

7.4 事务的相关配置

<tx:advice>中可以进行事务的相关配置:

<tx:advice id="txAdvice">
  <tx:attributes>
    <tx:method name="*"/>
    <tx:method name="find*" read-only="true"/>
  </tx:attributes>
</tx:advice>

<tx:method>中的属性:

  • name:指定配置的方法。*表示所有方法,find*表示所有以find开头的方法。
  • read-only:是否是只读事务,只读事务不存在数据的修改,数据库将会为只读事务提供一些优化手段,会对性能有一定提升,建议在查询中开启只读事务。
  • timeout:指定超时时间,在限定的时间内不能完成所有操作就会抛异常。默认永不超时
  • rollback-for:指定某个异常事务回滚,其他异常不回滚。默认所有异常回滚。
  • no-rollback-for:指定某个异常不回滚,其他异常回滚。默认所有异常回滚。
  • propagation:事务的传播行为
  • isolation:事务的隔离级别

7.5 事务的传播行为

事务传播行为是指多个含有事务的方法相互调用时,事务如何在这些方法间传播。

如果在service层的方法中调用了其他的service方法,假设每次执行service方法都要开启事务,此时就无法保证外层方法和内层方法处于同一个事务当中。

// method1的所有方法在同一个事务中
public void method1(){
  // 此时会开启一个新事务,这就无法保证method1()中所有的代码是在同一个事务中
  method2();
  System.out.println("method1");
}
public void method2(){
  System.out.println("method2");
}

事务的传播特性就是解决这个问题的,Spring帮助我们将外层方法和内层方法放入同一事务中。

传播行为 介绍
REQUIRED 默认。支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
MANDATORY 支持当前事务,如果当前没有事务,就抛出异常。
REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。
NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
NESTED 必须在事务状态下执行,如果没有事务则新建事务,如果当前有事务则创建一个嵌套事务

7.6 事务的隔离级别

事务隔离级别反映事务提交并发访问时的处理态度,隔离级别越高,数据出问题的可能性越低,但效率也会越低。

隔离级别 脏读 不可重复读 幻读
READ_UNCOMMITTED(读取未提交内容) Yes Yes Yes
READ_COMMITTED(读取提交内容) No Yes Yes
REPEATABLE_READ(重复读) No No Yes
SERIALIZABLE(可串行化) No No No

如果设置为DEFAULT会使用数据库的隔离级别。

  • SqlServer , Oracle默认的事务隔离级别是READ_COMMITTED
  • Mysql的默认隔离级别是REPEATABLE_READ

7.7 注解配置声明式事务

Spring支持使用注解配置声明式事务。用法如下:

1、注册事务注解驱动

<!--事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="datasource"/>
    </bean>
    <!--注册事务注解驱动-->
    <tx:annotation-driven transaction-manager="transactionManager"/>

2、在需要事务支持的方法或类上加@Transactional

@Service
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)
public class UserService {}

配置类代替xml中的注解事务支持:在配置类上方写@EnableTranscationManagement

@Configuration
@ComponentScan("com.zj")
@EnableTransactionManagement
public class SpringConfig {
  @Bean
  public DataSource getDataSource(){
    DruidDataSource druidDataSource = new DruidDataSource();
    druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    druidDataSource.setUrl("jdbc:mysql:///mybatis");
    druidDataSource.setUsername("root");
    druidDataSource.setPassword("123456");
    return druidDataSource;
   }
  @Bean
  public SqlSessionFactoryBean getSqlSession(DataSource dataSource){
    SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
    sqlSessionFactoryBean.setDataSource(dataSource);
    return sqlSessionFactoryBean;
   }
  @Bean
  public MapperScannerConfigurer getMapperScanner(){
    MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
    mapperScannerConfigurer.setBasePackage("com.zj.dao");
    return mapperScannerConfigurer;
   }
  @Bean
  public DataSourceTransactionManager getTransactionManager(DataSource dataSource){
    DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
    dataSourceTransactionManager.setDataSource(dataSource);
    return dataSourceTransactionManager;
   }
}


相关文章
|
17天前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
30天前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
40 4
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
137 1
|
27天前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
34 0
|
21天前
|
前端开发 Java 数据库连接
Spring 框架:Java 开发者的春天
Spring 框架是一个功能强大的开源框架,主要用于简化 Java 企业级应用的开发,由被称为“Spring 之父”的 Rod Johnson 于 2002 年提出并创立,并由Pivotal团队维护。
41 1
Spring 框架:Java 开发者的春天
|
14天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
32 2
|
13天前
|
消息中间件 NoSQL Java
springboot整合常用中间件框架案例
该项目是Spring Boot集成整合案例,涵盖多种中间件的使用示例,每个案例项目使用最小依赖,便于直接应用到自己的项目中。包括MyBatis、Redis、MongoDB、MQ、ES等的整合示例。
61 1
|
21天前
|
Java 数据库连接 开发者
Spring 框架:Java 开发者的春天
【10月更文挑战第27天】Spring 框架由 Rod Johnson 在 2002 年创建,旨在解决 Java 企业级开发中的复杂性问题。它通过控制反转(IOC)和面向切面的编程(AOP)等核心机制,提供了轻量级的容器和丰富的功能,支持 Web 开发、数据访问等领域,显著提高了开发效率和应用的可维护性。Spring 拥有强大的社区支持和丰富的生态系统,是 Java 开发不可或缺的工具。
|
1月前
|
NoSQL Java Redis
redis的基本命令,并用netty操作redis(不使用springboot或者spring框架)就单纯的用netty搞。
这篇文章介绍了Redis的基本命令,并展示了如何使用Netty框架直接与Redis服务器进行通信,包括设置Netty客户端、编写处理程序以及初始化Channel的完整示例代码。
42 1
redis的基本命令,并用netty操作redis(不使用springboot或者spring框架)就单纯的用netty搞。
|
28天前
|
人工智能 开发框架 Java
总计 30 万奖金,Spring AI Alibaba 应用框架挑战赛开赛
Spring AI Alibaba 应用框架挑战赛邀请广大开发者参与开源项目的共建,助力项目快速发展,掌握 AI 应用开发模式。大赛分为《支持 Spring AI Alibaba 应用可视化调试与追踪本地工具》和《基于 Flow 的 AI 编排机制设计与实现》两个赛道,总计 30 万奖金。