Spring整理三

Spring JDBC 框架

1、前言

在使用普通的 JDBC 数据库时,就会很麻烦的写不必要的代码来处理异常,打开和关闭数据库连接等。

Spring 框架针对数据库开发中的应用提供了 JDBCTemplate 类,该类是 Spring 对 JDBC 支持的核心,它提供了所有对数据库操作功能的支持。

Spring 框架提供的JDBC支持主要由四个包组成,分别是 core(核心包)、object(对象包)、dataSource(数据源包)和 support(支持包),org.springframework.jdbc.core.JdbcTemplate 类就包含在核心包中。

2、核心类

JdbcTemplate 类继承自抽象类 JdbcAccessor,同时实现了 JdbcOperations 接口。其直接父类 JdbcAccessor 为子类提供了一些访问数据库时使用的公共属性,具体介绍如下:

  • DataSource
    其主要功能是获取数据库连接,具体实现时还可以引入对数据库连接的缓冲池和分布式事务的支持,它可以作为访问数据库资源的标准接口。
  • SQLExceptionTranslator
    org.springframework.jdbc.support.SQLExceptionTranslator 接口负责对 SQLException 进行转译工作。通过必要的设置或者获取 SQLExceptionTranslator 中的方法,可以使 JdbcTemplate 在需要处理 SQLException 时,委托 SQLExceptionTranslator 的实现类完成相关的转译工作。

JdbcOperations 接口定义了在 JdbcTemplate 类中可以使用的操作集合,包括添加、修改、查询和删除等操作。

JdbcDaoSupport则对JdbcTemplate进行了封装,所以要操作JdbcTemplate,或只需要继承JdbcDaoSupport即可。

3、示例

首先引入jar包:spring-jdbc、org.springframework.transaction、org.springframework.jdbc、mysql-connector-java
https://mvnrepository.com/artifact/mysql/mysql-connector-java
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

事务管理

1、前言

事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。

例如:在关系数据库中,一个事务可以是一条SQL语句,一组SQL语句或整个程序。

比如我有一个业务,需要先对数据库插入数据再修改数据,假如这时修改失败了,这会导致数据出错。此时加上事物,当这两条操作只要有一个出现问题,那就全部回滚,所有数字都不写入数据库。

一个数据库事务是一个被视为单一的工作单元的操作序列。这些操作应该要么完整地执行,要么完全不执行。以确保数据完整性和一致性。

因此,事务应该具有4个属性:原子性、一致性、隔离性、持续性。这四个属性通常称为ACID特性:

  • 原子性: 事务应该当作一个单独单元的操作,这意味着整个序列操作要么是成功,要么是失败的。
  • 一致性: 指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。
    • 拿转账来说,假设A和B加起来一共5000元,那么不管A和B之间如何转账,转几次账,事务结束后两人的钱相加起来应该还得是5000,不能因为转到一半系统宕机了,导致A扣了1000,但是B没收到,这就是事务的一致性。
  • 隔离性: 可能同时处理很多有相同的数据集的事务,每个事务应该与其他事务隔离,以防止数据损坏。
    • 同转账,A有1000元,此时B给A转了500,结果还没转完,C又给A转了200,此时B完成时A有1500,B完成时A变成了1200,缺了500,这是因为B是按照A有1000算的。
  • 持久性: 一个事务一旦完成全部操作后,这个事务的结果必须是永久性的,不能因系统故障而从数据库中删除。

事务分局部事物和全局事务:局部事务是特定于一个单一的事务资源,如一个 JDBC 连接,而全局事务可以跨多个事务资源事务,如在一个分布式系统中的事务。

2、Spring的事务

  • 1、 支持两种类型的事务管理:编程式和声明式
    • 编程式:自己手动控制事务。

      • 属于细粒度的事务控制,可以对指定的方法、指定的方法的某几行添加事务控制。
      • 使用比较灵活,但开发起来比较繁琐, 每次都要开启、提交、回滚,维护也麻烦。
      • 开启事务后一定要手动释放(提交或回滚),否则长期占用内存,有可能报事务异常。
    • 声明式:Spring提供使用注释或 XML 配置来管理事务,让事务从业务代码中分离。

      • 属于粗粒度的事务控制, 只能给整个方法应用事务,不可以对方法的某几行应用事务。
      • 不想使用时直接移除配置,实现了对事务控制的最大程度的解耦。
      • 核心实现基于Aop。
      • Spring的事务属性分别为传播行为、隔离级别、只读和超时属性,这些属性提供了事务应用的方法和描述策略。

3、Spring事务的核心

  • 1、核心接口: spring-tx是Spring提供的用于事务管理的jar包,其中包括事务管理的三个核心接口:PlatformTransactionManager、TransactionDefinition 和 TransactionStatus。

    • PlatformTransactionManager接口是Spring提供的平台事务管理器,用于管理事务。该接口中提供了三个事务操作方法:
      • TransactionStatus getTransaction(TransactionDefinition definition):用于获取事务状态信息。
      • void commit(TransactionStatus status):用于提交事务。
      • void rollback(TransactionStatus status):用于回滚事务。
      • 在项目中,Spring 将 xml 中配置的事务详细信息封装到对象 TransactionDefinition 中,然后通过事务管理器的 getTransaction() 方法获得事务的状态(TransactionStatus),并对事务进行下一步的操作。
    • TransactionDefinition 接口是事务定义(描述)的对象,它提供了事务相关信息获取的方法,其中包括五个操作
      • String getName():获取事务对象名称。
      • int getIsolationLevel():获取事务的隔离级别。
      • int getPropagationBehavior():获取事务的传播行为。
      • int getTimeout():获取事务的超时时间。
      • boolean isReadOnly():获取事务是否只读。
    • TransactionStatus 接口是事务的状态,它描述了某一时间点上事务的状态信息:
      • boolean hasSavepoint():获取是否存在保存点。
      • boolean isCompleted() :获取事务是否完成。
      • boolean isNewTransaction() :获取是否是新事务。
      • boolean isRollbackOnly() :获取是否回滚。
      • void setRollbackOnly(): 设置事务回滚。
      • void flush():刷新事务。
  • 2、传播行为
    在这里插入图片描述
    在事务管理过程中,传播行为可以控制是否需要创建事务以及如何创建事务。
    通常情况下,数据的查询不会改变原数据,所以不需要进行事务管理,而对于数据的增加、修改和删除等操作,必须进行事务管理。如果没有指定事务的传播行为,则 Spring3 默认的传播行为是 required。

  • 3、隔离级别

    • 事务的并发操作中可能会出现脏读,不可重复读,幻读:

      • 脏读(误读):事务A更新了某个数据项X,但是由于某种原因,事务A出现了问题,于是要把A回滚。但是在回滚之前,另一个事务B读取了数据项X的值(A更新后),A回滚了事务,数据项恢复了原值。事务B读取的就是数据项X的就是一个“临时”的值,就是脏数据,这就是脏读。
      • 不可重复读:是指在数据库访问中,一个事务范围内两个相同的查询却返回了不同数据。是由于查询时系统中其他事务修改的提交而引起的。比如事务T1读取某一数据,事务T2读取并修改了该数据,T1为了对读取值进行检验而再次读取该数据,便得到了不同的结果。对应的是UPDATE操作。
      • 幻读(虚读):指当事务不是独立执行时发生的一种现象。例如,A事务对一个表中的全部数据进行了修改。同时,B事务向这个表中插入一行新的数据。那么,以后就会发生操作A事务的用户发现表中还有没有修改的数据行,就好像发生了幻觉一样。对应INSERT操作。
    • ISOLATION_DEFAULT:默认隔离级别。

      • 大多数数据库默认的事务隔离级别是Read committed(读提交),比如Sql Server , Oracle。Mysql的默认隔离级别是Repeatable read(重复读)。
    • ISOLATION_READ_UNCOMMITTED:读未提交

      • 一个事务可以读取另一个未提交事务的数据。
      • 可能发生脏读、不可重复读和幻读。
    • ISOLATION_READ_COMMITTED:读提交

      • 一个事务要等另一个事务提交后才能读取数据。
      • 能够阻止脏读;但可能发生不可重复读和幻读。
    • ISOLATION_REPEATABLE_READ:重复读

      • 在开始读取数据(事务开启)时,不再允许修改操作。
      • 能够阻止脏读、不可重复读;但可能发生幻读。
    • ISOLATION_SERIALIZABLE:序列化

      • 是最高的事务隔离级别,在该级别下,事务串行化顺序执行。
      • 能够阻止脏读、不可重复读、幻读。
      • 效率低下,比较耗数据库性能,一般不使用。

4、编程式事务

直接使用 PlatformTransactionManager 来实现编程式事务。要开始一个新事务,你需要有一个带有适当的 transaction 属性的 TransactionDefinition 的实例。

当 TransactionDefinition 创建后,可以通过调用 getTransaction() 方法来开始事务,该方法会返回 TransactionStatus 的一个实例。 TransactionStatus 对象帮助追踪当前的事务状态,并且最终,如果一切运行顺利,可以使用 PlatformTransactionManager 的 commit() 方法来提交这个事务,否则的话,可以使用 rollback() 方法来回滚整个操作。

让我们把上边jdbc的例子改改就可以实现:引入spring-tx包
修改StudentJDBCTemplate,添加事务相关的实现。
在这里插入图片描述
在这里插入图片描述
修改xml配置:
在这里插入图片描述
此时运行后你会发现数据库里没有插入数据。当你把rollback方法修改为commit才可插入。

5、声明式事务

由于在实际开发中,编程式事务管理很少使用,所以重点看看 Spring 的声明式事务管理。

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

Spring 实现声明式事务管理主要有两种方式:

  • 1、基于XML方式实现:整体上还是改造上边的例子,但因为比较重要,还是贴全了
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 2、基于Annotation注解方式实现
    使用注解则及其简单:
    • 1)、在 Spring 容器中注册驱动,<tx:annotation-driven transaction-manager=“txManager”/>,后边事务管理器可写可不写。
    • 2)、在需要使用事务的业务类或者方法中添加注解 @Transactional,并配置 @Transactional 的参数。
      在这里插入图片描述
      在这里插入图片描述
      注意开启注解,因为我在xml里有配置StudentJDBCTemplate的bean,所以就没开注解扫描。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值