SpringBoot @Transactional事务详解

事务用处及作用

事务主要是保证数据统一、一致的一种操作。

详细的一些专用术语在此这里不会说太多,如需了解自行百度了(还不是枯燥乏味),大致就是这意思。

事务用处

比如坤坤坤坤拿着100元去买鸡,一个鸡10元,在没有事务的情况下,坤坤把100元交给了卖鸡老板,此时城管来了,老板突然跑路(这里指的是在支付时,数据出现异常),那么坤坤的100元也就没了,鸡也没买到。坤坤哭死…

如果有事务的场景下,坤坤拿着100元去买鸡,坤坤把100元给了卖鸡老板,老板突然跑路(发生异常),支付系统会自动回滚,把100元还给坤坤,这样数据就不会出错了。还有个场景,比如卖鸡老板正在找给坤坤钱的时候,此时另一个人长得也像坤坤的人来买鸡(这里指多线程并发),老板此时如果顾不过来,找钱就会出现问题,比如少给了坤坤20元,或者多给了坤坤20元等等操作。

在这里插入图片描述

当Java中一个方法内有多次对数据库的增删改查等操作,并且这些操作之间有一些关联关系,如果方法执行一半出问题报错,后面的操作将不会执行,造成数据异常,但是使用了事务以后可以如果中途执行失败,可以回退到方法执行之前,保证数据不出问题。

总之就是事务保障了数据交互时的安全性,数据要么都修改、要么都回滚。

事务四大特性

1、原子性

事务要么全部都被执行,要么就全都不被执行,如果有子事务提交失败,那么其他子事务对数据库的操作将被回滚,数据库回到事务提交前的状态;如果全部子事务都提交成功,则所有的数据库操作都会被提交

2、一致性

事务的执行使得数据库从一种正确状态转换成另一种正确状态

3、隔离性

一个事务的执行不能被其他事务所影响

4、持久性

事务一旦提交,就会永久保存在数据库中,及时数据库服务器发生故障,也不会丢失提交事务的操作。

事务四大隔离级别

  1. @Transactional(isolation = Isolation.READ_UNCOMMITTED):读取未提交数据(会出现脏读,不可重复读) 基本不使用
  2. @Transactional(isolation = Isolation.READ_COMMITTED):读取已提交数据(会出现不可重复读和幻读)
  3. @Transactional(isolation = Isolation.REPEATABLE_READ):可重复读(会出现幻读)
  4. @Transactional(isolation = Isolation.SERIALIZABLE):串行化

事务实现方式

Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,Spring是无法提供事务功能的。
Spring事务实现主要有两种方法:编程式:beginTransaction()、commit()、rollback()等事务管理相关的方法。
还有声明式,使用注解@Transactional

正常情况下来说,SpringBoot默认是有事务的,默认也还会开启,不需要在Application.java类中在次声明@EnableTransactionManagement注解。

注意:@Transactional注解如果放到不是public修饰的方法或类上会导致事务失效。如果使用mysql引擎是MyISAM那么事务也不会起作用,MyISAM不支持事务,可以改为InnoDB引擎。

建立模拟数据库

这里我创建了3张表,分别是:

  • d_user: 用户表
  • d_detail:明细表
  • d_shop:商品表
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

d_shop看到这张表了吗?为了业务连贯性和方便理解,这里一定要注意!因为它没用。

事务注解

到这里你就不得了了,你现在已经很牛批了,最起码知道事务是什么,不加事务是什么后果。

接下来学会实际应用那还得了?

添加事务是用的是@Transactional注解。

  • @Transactional,不加任何参数时,默认会回滚运行时异常及其子类,其它范围之外的异常 Spring 不会帮我们去回滚数据
  • @Transactional(rollbackFor = Exception.class),如果加上rollbackFor 参数,会回滚所有异常类,前提下一定要在catch中抛出相关异常类,否则事务还是失效的。

下面是异常类和子类关系图,@Transactional,不加任何参数时,默认只会回滚RuntimeException和子类,其他类不会回滚:

在这里插入图片描述
在这里插入图片描述

不使用事务

1、第一种情况,不使用任何事务
在这里插入图片描述
这种操作,就是没有使用任务事务的,如果程序不出错,那么数据正常执行没有问题。

金额 - 10,并且明细表中有购买记录。

在这里插入图片描述
在这里插入图片描述
2、第二种情况

如果这时候,某些程序发生错误,比如下面最常见的 不能被0整出异常。

在这里插入图片描述

会发现,钱扣了… 却没有明细,没有明细就意味着数据不完整。

在这里插入图片描述
在这里插入图片描述
后台完美的抛出了异常

在这里插入图片描述

使用事务

1、第一种,只有@Transactional注解,这种情况只会 回滚 RuntimeException和子类,其他异常将不会回滚,这种不用特意抛出异常。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

即使后台出错,并且还保持数据的完整性。

2、第二种,使用 @Transactional(rollbackFor = Exception.class) 注解,默认会回滚所有事务,前提下,一定要主动抛出异常,否则事务是不会生效的。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3、第三种,可以指定回滚事务异常类,这里需要排除不用回滚的异常类,同样需要异常抛出。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
4、第四种,可以不依赖 throw new NullPointerException("") 手动执行事务回滚。

// 手动回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
@Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean payShop(String shopId) {
        // 查询商品金额
        DShop dShop = dShopMapper.selectById(shopId);

        // 查询用户现有金额
        DUser dUser = dUserMapper.selectById("1");

        // 更新用户金额
        double newMoney = dUser.getMoney()-dShop.getShopMoney();
        dUser.setMoney(newMoney);
        dUserMapper.updateById(dUser);

        try {
            String a = null;
            boolean equals = a.equals("2");
        } catch (Exception e) {
            e.printStackTrace();

            // 手动执行回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }

        /*try {
            String[] str = new String[1];
            System.out.println(str[5]);
        } catch (Exception e) {
            e.printStackTrace();

            // 如果设置的 @Transactional(rollbackFor = {Exception.class}) 那么一定要抛出相关异常,否则事务不生效
            throw new ArrayIndexOutOfBoundsException("数组超了");
        }*/

        DDetail dDetail = new DDetail();
        dDetail.setUserId(dUser.getUserId());
        dDetail.setPayMoney(dShop.getShopMoney());
        dDetail.setShopId(dShop.getShopId());
        dDetailMapper.insert(dDetail);

        return true;
    }

效果是一样的,就不贴图片了。

其他参考

https://blog.csdn.net/yuxiangdeming/article/details/125243814

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/4580.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JAVA ---程序流程

(一)引言 在生活中,我们经常会发现在医院或者官方机构办事是要走流程的,同样的程序必须能操控自己的世界,在执行过程中作出判断与选择。在Java中,通过流程控制语句可实现程序执行流程的随意控制&#xff0…

C#中使用I/O文件流

流,即是二进制数值,文件和流 I/O(输入/输出)是指在存储媒介中传入或传出数据。 在 .NET 中,System.IO 命名空间包含允许以异步方式和同步方式对数据流和文件进行读取和写入操作的类型。 这些命名空间还包含对文件执行压…

Android开发 Intent

1. Intent 在组件之间传递信息,一般需要设置发送方,接收方和数据。 下图是Intent 的常用属性: 2. Intent分类 1)显式Intent:精确匹配发送方和接收方 方法一: startActivity(new Intent(this,MainActiv…

USB抓包分析

1、USB传输协议基本概念 一个传输(控制、批量、中断、等时):由多个事务transaction组成; 一个事务transaction (IN、OUT、SETUP):由一多个包Packet组成。USB数据在主机与usb设备间被传输,之间的关联叫做管道pipe。一个USB设备可以…

图片转字符画

目录一、字符画二、制作方式一、字符画 字符画:用字符填充创作的人物或动物图片,就像下面这样: 二、制作方式 1.使用Ps的文字工具和蒙版工具来实现 可以看下YouTube上这个教程视频:Photoshop CS6 Tutorial: How to Make an Edi…

企业电子招投标采购系统源码之首页设计

功能模块: 待办消息,招标公告,中标公告,信息发布 描述: 全过程数字化采购管理,打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力,为外部…

详解TCP、HTTP中的保活机制 | Keepalive和Keep-Alive

目录 🌲 HTTP 的 Keep-Alive 🌲 TCP 的 Keepalive 🌲 最后总结 🌲 参考资料 TCP 的 Keepalive 和 HTTP 的 Keep-Alive 是一个东西吗? 这是个好问题,应该有不少人都会搞混,因为这两个东西看上…

DNS协议--笔记

引自: 什么是DNS? - 知乎 (zhihu.com) 超详细 DNS 协议解析 - 知乎 (zhihu.com) IP 地址:一长串能够唯一地标记网络上的计算机的数字域名:又称网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组…

rust语言精要

rust基本组成 编译器:Rust是一门静态编译型语言。Rust官方的编译器叫rustc,负责将 Rust源代码编译为可执行文件或其他库文件(.a、.so、.lib、.dll等)。特点是跨平台的,后端用了LLVM。 核心库和标准库 Rust语言的语法由…

Prometheus之PromQL语法详解及使用方法

本文是向大家介绍Prometheus中PromQL的查询语法以及常用语句,可以帮助大家理解和掌握Prometheus的查询语言。1、简介Prometheus是通过指标名称(metrics name)以及对应的一组标签(labelset)唯一定义一条时间序列。指标名…

如何选择Facebook的各种广告形式来获取用户?

Facebook广告是吸引潜在客户的重要工具,但盲目投放广告却很难达到理想效果。在选择广告格式时,需要考虑到品牌和业务目标,以及目标受众的特征和偏好。下面介绍8种Facebook广告格式,不论您是想用视频、图片或文字,还是结…

云端Docker搭建ABY库以及本地CLion使用

文章目录ABY的搭建以及使用前言ABY库的下载、安装及测试CLion配置后续杂项项目改名使用其他的库最后ABY的搭建以及使用 前言 仅做记录,仅供参考,不同人有不同的使用方式命令手敲,可能有错,自己辨识勿问,我懂的也不多…

什么牌子的蓝牙耳机音质好又便宜?国产音质好的蓝牙耳机推荐

目前的蓝牙耳机市场涌现了越来越多的蓝牙耳机,不同价位主打不同的性能,有主打佩戴的,主打音质的,主打降噪的,主打游戏的等等。那么,什么牌子的蓝牙耳机音质好又便宜?针对这个问题,我…

Redis详解(redis线程模式、数据持久化机制、主从复制、缓存穿透、缓存击穿等)

一.redis概述redis主要用作数据库、缓存和消息中间件, 支持多种语言, 是基于内存的key-value数据结构存储系统. redis支持数据的持久化, 可以将内存中的数据保存在磁盘中, 重启的时候可以再次加载进行使用.redis不仅仅支持key-value数据结构, 还支持list, set, hash等数据结构.…

CHAPTER 7 HPC集群部署 - hadoop

HPC集群部署 - hadoop1. 介绍2. 优点3. 架构及相关组件3.1 HDFS3.1.1 NameNode3.1.2 DataNode3.1.3 Secondary NameNode3.1.4 Client(客户端)3.2 Mapreduce(分布式计算框架)3.3. HBase(分布式列存储数据库)3.4 Zookeeper&#xff…

【其它】玩一玩无线网桥PicoStation M2

一、无线网桥是什么? 无线网桥就是代替网线实现网络连接的装置。看下面这个场景,摄像头与录像机之间可以直接用网线连接,但遇到两者相距较远的情况,铺设网线成本太高,这时候可以用无线网桥进行连接。无线网桥一般成对…

SSM项目之租赁汽车管理

项⽬描述 汽⻋租赁管理系统,管理系统中不仅有客户的管理还有⻋辆租赁的管理,租赁⻋辆公司对于租⻋的流程,租⻋过程的问题,对于客户的维护及不同维度统计租⻋的情况做数据化管理,⽅便租⻋公司更好的维护⻋辆和⻋辆的信…

易基因: m6A RNA甲基化研究的前期探索性实验思路|干货系列

大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。 近年来,m6A RNA甲基化作为国家自然科学基金表观遗传学研究的热门领域,相关研究成果层出不穷,高分文章不断。研究方向包括疾病发生发展、发育和分化、环…

误删磁盘恢复方法

一、工具如下:1、磁盘分区恢复工具(分区助手 9.8.0)---链接:https://pan.baidu.com/s/1t3siEwtYZl7XtcNJ8t5oLg 提取码:9tsy2、DiskGenius 磁盘信息查看工具(修复要收费):链接:https://pan.baid…

(源码篇02)webpack5中的事件调度系统和NormalModuleFactary核心逻辑

1. 书接上回,从 this.factorizeQueue.add(options, callback); 开始 不是很清楚上下文的兄弟,可以去看下我之前写的 (源码篇01)浅析webpack5中Compiler中重要的hook调用过程。 此文比较干,各位读者开始阅读前&#xf…
最新文章