百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 文章教程 > 正文

详细介绍一下SpringBoot中的声明式事务

xsobi 2024-12-14 15:45 1 浏览

在Spring Boot中使用声名式事务主要是通过注解的方式来进行管理。而不是通过编程手动管理事务边界。SpringBoot通过Spring中的@Transactional注解来实现声明式事务。下面我们就来详细介绍一下在SpringBoot中如何使用声明式事务。

@Transactional 注解

@Transactional是声明式事务管理的核心注解,可以用在类或者方法级别,用来定义某个方法或者类中所有方法的事务属性,如下所示。

import org.springframework.transaction.annotation.Transactional;

@Service
public class UserService {

    @Transactional
    public void createUser(User user) {
        // 数据库操作
    }

    @Transactional(readOnly = true)
    public User getUser(Long id) {
        // 数据库操作
    }
}

事务属性介绍

在@Transactional注解中提供了很多的属性来对事务的行为进行定义,而下面我们就来介绍一下这些注解属性的含义。

propagation

这个属性主要是用来指定事务的传播行为,其常见值属性值包括如下一些。

  • REQUIRED(默认):如果当前有事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
  • REQUIRES_NEW:总是创建一个新的事务,如果当前存在事务,则将当前事务挂起。
  • NESTED:如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则创建一个新的事务。
  • 其他:MANDATORY、NOT_SUPPORTED、NEVER、SUPPORTS。

isolation

用来设置事务隔离级别的属性,事务隔离级别通常由如下几个级别。

  • DEFAULT(默认):使用底层数据库的默认隔离级别。
  • READ_UNCOMMITTED:允许脏读、不可重复读和幻读。
  • READ_COMMITTED:防止脏读,但仍允许不可重复读和幻读。
  • REPEATABLE_READ:防止脏读和不可重复读,但仍允许幻读。
  • SERIALIZABLE:防止脏读、不可重复读和幻读。

timeout

用来指定事务超时时间,默认值是指底层的事务管理器指定的默认的超时时间,如果没有设置,那么该属性值就为-1表示没有超时时间。

readOnly

是否只读事务。设置为true可以提示底层数据库引擎优化事务。

rollbackFor

用来指定一个异常的列表,当发生这些指定的异常的时候,进行事务的回滚操作,在默认情况下Spring框架检查的就是Exception异常,而不会检查RuntimeException。

noRollbackFor

用来指定异常列表,当发生当前列表中的异常的时候,事务不会进行回滚。

事务传播行为(Propagation)

事务的传播行为定义了事务操作的边界以及事务操作的规则,下面是一些整理好的事务传播行为,如下所示。

  • REQUIRED:如果当前存在事务操作,那么就将操作事务添加到该事务中,但是如果当前没有执行的事务,那么就创建一个新的事务操作。
  • REQUIRES_NEW:会一直创建新的事务操作,如果当前存在事务操作,那么就会将当前事务挂起然后创建新的事务操作。
  • NESTED:如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则创建一个新的事务。
  • SUPPORTS:如果当前有事务,则加入事务;如果当前没有事务,也可以正常执行。
  • NOT_SUPPORTED:不支持事务,如果当前有事务,则将当前事务挂起。
  • NEVER:不支持事务,如果当前有事务,则抛出异常。
  • MANDATORY:必须在一个事务中运行,如果当前没有事务,则抛出异常。

事务隔离级别(Isolation)

我们都知道事务是具有隔离性的,而事务的隔离级别则是定义了一个事务可能会遇到的一些数据一致性的问题,下面是常见的一些事务隔离级别情况整理,如下所示。

  • DEFAULT:使用底层数据库的默认隔离级别。
  • READ_UNCOMMITTED:允许脏读、不可重复读和幻读。
  • READ_COMMITTED:防止脏读,但仍允许不可重复读和幻读。
  • REPEATABLE_READ:防止脏读和不可重复读,但仍允许幻读。
  • SERIALIZABLE:防止脏读、不可重复读和幻读。

如何配置声明式事务

在SpringBoot中提供了自动配置事务管理器的机制,如果在实际操作中我们需要进行手动调整事务操作,可以通过application.properties或者通过Java配置类进行配置。如下所示。

通过配置文件配置

spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.transaction.default-timeout=30
spring.transaction.rollback-on-commit-failure=true

通过Java配置类配置

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;

@Configuration
@EnableTransactionManagement
public class TransactionConfig implements TransactionManagementConfigurer {

    @Bean
    public PlatformTransactionManager txManager() {
        return new DataSourceTransactionManager(dataSource());
    }

    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return txManager();
    }
}

存在问题

  • 事务失效问题:事务方法内部调用自身的另一个事务方法时,事务不会生效。可以通过AOP代理或者在不同的类中进行调用来解决。
  • 只读事务:只读事务,也就是说只会读取数据,而不能对数据进行写入,否则可能会导致属于不一致的异常出现。
  • 事务嵌套:通过NESTED当做事务传播行为的时候,可以实现事务的嵌套,而在使用REQUIRES_NEW传播行为的时候,就会新开启一个事务操作,而不依赖于当前事务。

通过上述配置和使用,Spring Boot中的声明式事务管理可以大大简化事务管理代码,提高代码的可读性和可维护性。

相关推荐

好用的云函数!后端低代码接口开发,零基础编写API接口

前言在开发项目过程中,经常需要用到API接口,实现对数据库的CURD等操作。不管你是专业的PHP开发工程师,还是客户端开发工程师,或者是不懂编程但懂得数据库SQL查询,又或者是完全不太懂技术的人,通过...

快速上手:Windows 平台上 cURL 命令的使用方法

在工作流程中,为了快速验证API接口有效性,团队成员经常转向直接执行cURL命令的方法。这种做法不仅节省时间,而且促进了团队效率的提升。对于使用Windows系统的用户来说,这里有一套详细...

使用 Golang net/http 包:基础入门与实战

简介Go的net/http包是构建HTTP服务的核心库,功能强大且易于使用。它提供了基本的HTTP客户端和服务端支持,可以快速构建RESTAPI、Web应用等服务。本文将介绍ne...

#小白接口# 使用云函数,人人都能编写和发布自己的API接口

你只需编写简单的云函数,就可以实现自己的业务逻辑,发布后就可以生成自己的接口给客户端调用。果创云支持对云函数进行在线接口编程,进入开放平台我的接口-在线接口编程,设计一个新接口,设计和配置好接口参...

极度精神分裂:我家没有墙面开关,但我虚拟出来了一系列开关

本内容来源于@什么值得买APP,观点仅代表作者本人|作者:iN在之前和大家说过,在iN的家里是没有墙面开关的。...

window使用curl命令的注意事项 curl命令用法

cmd-使用curl命令的注意点前言最近在cmd中使用curl命令来测试restapi,发现有不少问题,这里记录一下。在cmd中使用curl命令的注意事项json不能由单引号包括起来json...

Linux 系统curl命令使用详解 linuxctrl

curl是一个强大的命令行工具,用于在Linux系统中进行数据传输。它支持多种协议,包括HTTP、HTTPS、FTP等,用于下载或上传数据,执行Web请求等。curl命令的常见用法和解...

Tornado 入门:初学者指南 tornados

Tornado是一个功能强大的PythonWeb框架和异步网络库。它最初是为了处理实时Web服务中的数千个同时连接而开发的。它独特的Web服务器和框架功能组合使其成为开发高性能Web...

PHP Curl的简单使用 php curl formdata

本文写给刚入PHP坑不久的新手们,作为工具文档,方便用时查阅。CURL是一个非常强大的开源库,它支持很多种协议,例如,HTTP、HTTPS、FTP、TELENT等。日常开发中,我们经常会需要用到cur...

Rust 服务器、服务和应用程序:7 Rust 中的服务器端 Web 应用简介

本章涵盖使用Actix提供静态网页...

我给 Apache 顶级项目提了个 Bug apache顶级项目有哪些

这篇文章记录了给Apache顶级项目-分库分表中间件ShardingSphere提交Bug的历程。说实话,这是一次比较曲折的Bug跟踪之旅。10月28日,我们在GitHub上提...

linux文件下载、服务器交互(curl)

基础环境curl命令描述...

curl简单使用 curl sh

1.curl--help#查看关键字2.curl-A“(添加user-agent<name>SendUser-Agent<name>toserver)”...

常用linux命令:curl 常用linux命令大全

//获取网页内容//不加任何选项使用curl时,默认会发送GET请求来获取内容到标准输出$curlhttp://www.baidu.com//输出<!DOCTYPEh...

三十七,Web渗透提高班之hack the box在线靶场注册及入门知识

一.注册hacktheboxHackTheBox是一个在线平台,允许测试您的渗透技能和代码,并与其他类似兴趣的成员交流想法和方法。它包含一些不断更新的挑战,并且模拟真实场景,其风格更倾向于CT...