Spring中的事务

embedded/2024/9/24 21:18:36/

目录

一.什么是事务?

二.事务的操作

三.Spring 中事务的实现

1.Spring 编程式事务(手动操作)

2.Spring 声明式事务

四.事务隔离级别

1.MySQL 事务隔离级别

2.Spring 事务隔离级别

五.Spring 事务传播机制


一.什么是事务?

事务是指作为单个逻辑工作单元执行的一系列操作,这些操作要么全部成功完成,要么全部失败回滚。在数据库系统中,事务是确保数据完整性和一致性的重要概念。

事务具有以下四个特性,通常被简称为 ACID 特性:

  1. 原子性(Atomicity):事务是一个原子操作单元,不可分割。这意味着事务中的所有操作要么全部提交成功,要么全部失败回滚,不存在部分操作成功部分操作失败的情况。

  2. 一致性(Consistency):事务执行前后,数据应该保持一致状态。如果事务执行失败,则系统应该回滚到事务执行前的状态,保证数据的一致性。

  3. 隔离性(Isolation):多个事务同时执行时,每个事务的操作应该与其他事务隔离开来,互不影响。这样可以防止并发执行时出现数据不一致的情况。

  4. 持久性(Durability):一旦事务提交成功,其对数据库的修改应该是永久性的,即使系统发生故障也不会丢失提交的数据。

在数据库系统中,通过事务可以将一系列数据库操作组合成一个逻辑单元,确保这些操作要么全部成功执行,要么全部失败回滚,从而保证数据的完整性和一致性。事务可以通过事务管理器来实现,常见的事务管理器包括数据库本身提供的事务支持以及应用程序框架(如Spring)提供的事务管理功能,而本文章就主要讲解Spring中提供的事务管理功能

二.事务的操作

事务的操作主要有三步:

  1.  开启事start transaction/ begin (⼀组操作前开启事务)
  2.  提交事务: commit (这组操作全部成功, 提交事务)
  3.  回滚事务: rollback (这组操作中间任何⼀个操作出现异常, 回滚事务)

三.Spring 中事务的实现

1.Spring 编程式事务(手动操作)

首先要认识spring中的两个对象:

  • DataSourceTransactionManager 事务管理器. ⽤来获取事务(开启事务), 提交或回滚事务
  • TransactionDefinition 事务的属性, 在获取事务的时候需要将 TransactionDefinition 传递进去来获得⼀个事务 TransactionStatus

示例如下:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;public class TransactionalService {@Autowiredprivate DataSourceTransactionManager transactionManager;public void performTransactionalOperation() {// 定义事务属性TransactionDefinition def = new DefaultTransactionDefinition();// 开始事务TransactionStatus status = transactionManager.getTransaction(def);try {// 执行业务逻辑,例如插入数据jdbcTemplate.update("INSERT INTO table_name (column1, column2) VALUES (?, ?)", value1, value2);// 提交事务transactionManager.commit(status);} catch (Exception ex) {// 出现异常,回滚事务transactionManager.rollback(status);throw ex;}}
}

在上述代码中,我们首先自动注入一个DataSourceTransactionManager 事务管理器,然后在方法中定义了一个事务的属性 def 并将 def 传入 dataSourceTransactionManager来开启事务,接着就可以执行业务的逻辑,如果正常完成就提交事务,捕获到异常就回滚事务

2.Spring 声明式事务

声明式事务的实现很简单, 只需要在需要事务的方法上添加 @Transactional 注解就可以实现了.无需手动开启事务和提交事务, 进入方法时自动开启事务, 方法执行完会自动提交事务, 如果中途发⽣了 没有处理的异常会⾃动回滚事务.

示例如下:

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class TransactionalService {@Transactionalpublic void performTransactionalOperation() {// 执行需要事务管理的业务逻辑}
}

下面是@Transactional注解的一些常用属性和用法:

  • 属性

    • propagation:事务的传播行为,指定事务的传播方式,如REQUIRED、REQUIRES_NEW等。
    • isolation:事务的隔离级别,指定事务的隔离级别,如READ_COMMITTED、SERIALIZABLE等。
    • timeout:事务超时时间,指定事务的超时时间,单位为秒。
    • readOnly:只读事务,指定事务是否为只读事务,可以优化性能。
    • rollbackFor:指定哪些异常会导致事务回滚。
    • noRollbackFor:指定哪些异常不会导致事务回滚。
  • 用法

    • 在类级别上添加@Transactional注解:表示该类中所有public方法都需要进行事务管理。
    • 在方法级别上添加@Transactional注解:表示该public方法需要进行事务管理,优先级高于类级别的注解。
    • 注解可以放在接口、类、方法等地方,Spring会根据AOP的代理机制为被注解的方法生成事务管理的代理。

注意:@Transactional 默认只在遇到运行时异常和Error时才会回滚, 非运行时异常不回滚. 如果我们需要所有异常都回滚, 需要来配置 @Transactional 注解当中的 rollbackFor 属性, 通过rollbackFor 这个属性指定出现何种异常类型时事务进行回滚

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class TransactionalService {@Transactional(rollbackFor = Exception.class)public void performTransactionalOperation() {// 执行需要事务管理的业务逻辑}
}

四.事务隔离级别

1.MySQL 事务隔离级别

MySQL 提供了多种事务隔离级别,用于控制并发事务执行时所遇到的问题。事务隔离级别定义了一个事务内部对其他事务的可见性以及并发读写操作的规则。以下是 MySQL 中常见的事务隔离级别:

1. 读未提交(Read Uncommitted)
   - 在该隔离级别下,事务中的修改会立即对其他事务可见,即使这些修改尚未被提交。这可能导致脏读(读取了未提交的数据)和不可重复读(同一查询在多次执行过程中返回不同的结果)。

2. 读提交(Read Committed)
   - 在该隔禅级别下,事务只能看见已经提交的数据,这可以避免脏读,但是依然可能出现不可重复读的问题。

3. 可重复读(Repeatable Read)
   - 在该隔离级别下,事务开始时读取的数据集是固定的,即使其他事务对数据进行了修改或者插入。这可以避免脏读和不可重复读,但可能出现幻读(一个事务在前后两次查询同样的条件,得到了不一样的结果)。

4. 序列化(Serializable)
   - 在该隔离级别下,事务顺序执行,事务之间彼此不会产生影响,可以避免脏读、不可重复读和幻读,但是性能较差,因为所有的并发事务都需要按顺序执行。

在 MySQL 中,默认的事务隔离级别是可重复读(Repeatable Read)。

2.Spring 事务隔离级别

Spring 事务管理器提供了与数据库事务隔离级别相对应的事务隔离选项。Spring 框架通过使用底层数据库的事务隔离级别来控制事务的隔离性。以下是 Spring 中支持的事务隔离级别:

  1. DEFAULT

    • 使用底层数据库的默认隔离级别,通常是数据库的默认隔离级别。
  2. READ_UNCOMMITTED

    • 读未提交隔离级别,与数据库的读未提交(Read Uncommitted)隔离级别相对应。
  3. READ_COMMITTED

    • 读已提交隔离级别,与数据库的读提交(Read Committed)隔离级别相对应。
  4. REPEATABLE_READ

    • 可重复读隔离级别,与数据库的可重复读(Repeatable Read)隔离级别相对应。
  5. SERIALIZABLE

    • 序列化隔离级别,与数据库的序列化(Serializable)隔离级别相对应。

你可以通过在 @Transactional 注解中设置 isolation 属性来指定事务的隔离级别.

示例如下:

@Transactional(isolation = Isolation.READ_COMMITTED)
public void myTransactionalMethod() {// 事务操作...
}

五.Spring 事务传播机制

Spring 的事务传播机制定义了在多个事务方法之间如何传播事务的行为。当一个事务方法调用另一个事务方法时,Spring 可以根据定义的事务传播行为来处理事务的边界。以下是 Spring 中常见的事务传播行为:

  1. REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认的传播行为。

  2. SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。

  3. MANDATORY:必须在一个事务中执行,如果当前没有事务,则抛出异常。

  4. REQUIRES_NEW:创建一个新的事务,并在它自己的事务中执行。如果当前存在事务,则将其挂起。

  5. NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,则将其挂起。

  6. NEVER:以非事务方式执行操作,如果当前存在事务,则抛出异常。

  7. NESTED:如果当前存在事务,则在嵌套事务中执行;如果当前没有事务,则执行类似于 REQUIRED 的操作。嵌套事务是相对于外部事务的一个独立的事务,但是它们可以利用外部事务的事务属性。

可以在 @Transactional 注解中使用 propagation 属性来指定事务传播行为

示例如下:

@Transactional(propagation = Propagation.REQUIRED)
public void myTransactionalMethod() {// 事务操作...
}

关于Spring中事务的介绍到这就结束了~


http://www.ppmy.cn/embedded/45533.html

相关文章

C语言题目:数字不重复排列

题目描述 有4个互不相同的数字,输出由其中三个不重复数字组成的排列。 输入格式 4个整数。 输出格式 所有排列 样例输入 1 2 3 4样例输出 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1 1 2 4 1 4 2 2 1 4 2 4 1 4 1 2 4 2 1 1 3 4 1 4 3 3 1 4 3 4 1 4 1 3 4 3 1 2…

算法(十三)回溯算法---N皇后问题

文章目录 算法概念经典例子 - N皇后问题什么是N皇后问题?实现思路 算法概念 回溯算法是类似枚举的深度优先搜索尝试过程,主要是再搜索尝试中寻找问题的解,当发生不满足求解条件时,就会”回溯“返回(也就是递归返回&am…

C++ ─── string的完整模拟实现

本博客实现了string的常见接口实现 下面是用到的一些函数,供大家回顾复习 改进1:流提取的改进 原来的代码中流提取中是一个一个字符提取,扩容频率太快,消耗太多 采用buff的方式,buff在栈上,开空间快。 ist…

【开发日记】ElementUI表单使用原生@submit提交表单数据

使用submit.native.prevent为el-form设置提交方法。 使用native-type为el-button设置原生按钮类型。 示例如下&#xff1a; <el-form class"search" submit.native.prevent"submitSearch"><div classsearch-item>人员ID :<el-input sizemi…

msgpack-c使用指南

msgpack MessagePack 是一种高效的二进制序列化格式&#xff0c;可在多种语言之间交换数据&#xff0c;但它更快、更小。小整数被编码为单个字节&#xff0c;而短字符串除了字符串本身之外只需要一个额外的字节。 msgpackcxx使用指南 msgpackcxx是一个纯头文件库。 安装指南…

新浪测试社招要个25K,第一次面大厂挂了

一面 1、讲下被测系统和你负责测试的模块功能&#xff1f; 2、为什么选择这个测试框架&#xff0c;这个测试框架有什么优缺点&#xff1f; 3、测试文件的目录&#xff0c;包含哪些包&#xff0c;这些之间是怎么调用的&#xff1f; 4、UI自动化和接口自动化都是怎么做的&…

K8S中Prometheus+Grafana监控

1.介绍 phometheus:当前一套非常流行的开源监控和报警系统。 运行原理&#xff1a;通过HTTP协议周期性抓取被监控组件的状态。输出被监控组件信息的HTTP接口称为exporter。 常用组件大部分都有exporter可以直接使用&#xff0c;比如haproxy,nginx&#xff0c;Mysql,Linux系统信…

基于翔云C#语言的身份证实名认证接口开发示例

现如今&#xff0c;安全与便捷成为了互联网服务的两大关键词。为了进一步提升用户体验并加强网络安全管理&#xff0c;国内多家主流App近日宣布完成一项重要功能升级——集成身份证实名认证系接口。这一举措标志着用户在进行App注册时&#xff0c;将享受到更加高效、安全的身份…