MySQL-----事务(详解)

server/2024/11/14 6:21:07/

目录

一.事务简介:

二.事务操作:

未控制事务:

事务的控制方法一:

 事务的控制方法二:

 三:事务的四大特性:

四.并发事务问题:

五.事务的隔离级别:


一.事务简介:

事务 是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系 统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败

比如,银行转账的操作就是一个典型的事务问题,举个例子:张三给李四转账1000块钱,张三银行账户的钱减少1000,而李四银行账户的钱要增加 1000。 这一组操作就必须在一个事务的范围内,要么都成功,要么都失败。

正常情况: 转账这个操作, 需要分为以下这么三步来完成 , 三步完成之后, 张三减少1000, 而李四 增加1000, 转账成功 :

异常情况: 转账这个操作, 也是分为以下这么三步来完成 , 在执行第三步是报错了, 这样就导致张 三减少1000块钱, 而李四的金额没变, 这样就造成了数据的不一致, 就出现问题了:

 

为了解决上述的问题,就需要通过数据的事务来完成,我们只需要在业务逻辑执行之前开启事务,执行 完毕后提交事务。如果执行过程中报错,则回滚事务,把数据恢复到事务开始之前的状态:

注意: 默认MySQL的事务是自动提交的,也就是说,当执行完一条DML语句时,MySQL会立即隐式的提交事务。

由于MySQL的事务自动提交的这种特性,就要求我们将设置修改为手动事务,以此来发现问题并且解决问题。

二.事务操作:

未控制事务:

  • 数据准备(这里我们根据上面的例子来说明问题):
# 数据准备
drop table if exists account;create table account(
id int primary key auto_increment comment 'ID',
name varchar(10) comment'年龄',
money double(10,2) comment '余额'
)comment '账户表';insert into account(name,money) values('张三',2000),('李四',2000);

1).测试正常情况:

# 未控制事务-- 1.查询张三余额
select * from account where name = '张三';-- 2.张三的余额减少1000
update account set money = money - 1000 where name = '张三';-- 3.李四的余额增加1000
update account set money = money + 1000 where name = '李四';

运行结果:

 2).异常情况(执行前要先将数据回复原样):

-- 将数据回复原样
update account set money = 2000 where name = '张三' or name = '李四';-- 1.查询张三余额
select * from account where name = '张三';-- 2.张三的余额减少1000
update account set money = money - 1000 where name = '张三';事务异常…… -- 异常情况,第三条SQL语句不会执行-- 3.李四的余额增加1000
update account set money = money + 1000 where name = '李四';

我们把数据都恢复到2000, 然后再次一次性执行上述的SQL语句(出错了.... 这句话不符合SQL语 法,执行就会报错),检查最终的数据情况, 发现数据在操作前后不一致了。 

执行结果:

为了解决这样的问题,我们引入事务的控制方法:

事务的控制方法一:

# 事务的控制方式一:1). 查看/设置事务提交方式
SELECT @@autocommit ;-- 查看事务的提交方式-- 1 为事务自动提交,0为事务手动提交SET @@autocommit = 0 ;-- 修改事务的提交方式2). 提交事务
COMMIT;3). 回滚事务
ROLLBACK;

具体实现:

-- 1). 查看/设置事务提交方式
select @@autocommit ; -- 1 为事务自动提交,0为事务手动提交
set @@autocommit = 0 ;-- 将事务设置为手动提交-- 1.查询张三余额
select * from account where name = '张三';-- 2.张三的余额减少1000
update account set money = money - 1000 where name = '张三';-- 3.李四的余额增加1000
update account set money = money + 1000 where name = '李四';-- 2). 提交事务
commit;-- 3). 回滚事务
rollback;

 注意:上述的这种方式,我们只是修改了事务的自动提交行为, 把默认的自动提交修改为了手动提 交, 此时我们执行的DML语句都不会提交, 只有执行到commit之后才会完成提交。

 事务的控制方法二:

# 事务的控制方法二:1). 开启事务
START TRANSACTION 或 BEGIN ;2). 提交事务
COMMIT;3). 回滚事务
ROLLBACK

具体实现:

# 控制事务的方式二:--->控制之前要设置为自动提交
SET @@autocommit = 1 ;-- 1). 开启事务
start transaction;-- 1.查询张三余额
select * from account where name = '张三';-- 2.张三的余额减少1000
update account set money = money - 1000 where name = '张三';-- 3.李四的余额增加1000
update account set money = money + 1000 where name = '李四';-- 2). 提交事务
commit;-- 3). 回滚事务
rollback;

 三:事务的四大特性:

  •  原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
  • 一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态。
  • 隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立 环境下运行。
  • 持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。

上面四个属性,可以简称为 ACID 。

原子性(Atomicity,或称不可分割性)

一致性(Consistency)

隔离性(Isolation,又称独立性)

持久性(Durability)。

四.并发事务问题:

  •  赃读:一个事务读到另外一个事务还没有提交的数据。
  •  不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复读。 

 

  • 幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据 已经存在,好像出现了 "幻影"。 

五.事务的隔离级别:

为了解决并发事务所引发的问题,在数据库中引入了事务隔离级别。主要有以下几种: 

注意:X表示该级别已经解决了对应问题,√ 表示该级别没有解决这个问题

读未提交【Read Uncommitted】: 在该隔离级别,所有的事务都可以看到其他事务没有提交的执行结果。(实际生产中不可能使用这种隔离级别的),但是相当于没有任何隔离性,也会有很多并发问题,如脏读,幻读,不可重复读等.

读提交【Read Committed】:该隔离级别是大多数数据库的默认的隔离级别(不是 MySQL 默认的)。它满足了隔离的简单定义:一个事务只能看到其他的已经提交的事务所做的改变。这种隔离级别会引起不可重复读,即一个事务执行时,如果多次 select,可能得到不同的结果。

可重复读【Repeatable Read】: 这是 MySQL 默认的隔离级别,它确保同一个事务,在执行中,多次读取操作数据时,会看到同样的数据行。但是有的数据库会有幻读问题。(MySQL不会)

串行化【Serializable】: 这是事务的最高隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决了幻读的问题。它在每个读的数据行上面加上共享锁。但是可能会导致超时和锁竞争(这种隔离级别太极端,实际生产基本不使用)

具体操作:

-- 1). 查看事务隔离级别
SELECT @@TRANSACTION_ISOLATION;-- 2). 设置事务隔离级别
SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED |
READ COMMITTED | REPEATABLE READ | SERIALIZABLE }

注意:事务隔离级别越高,数据越安全,但是性能越低。 

结语: 写博客不仅仅是为了分享学习经历,同时这也有利于我巩固知识点,总结该知识点,由于作者水平有限,对文章有任何问题的还请指出,接受大家的批评,让我改进。同时也希望读者们不吝啬你们的点赞+收藏+关注,你们的鼓励是我创作的最大动力!


http://www.ppmy.cn/server/43013.html

相关文章

Docker | 基础指令

环境:centos8 参考: 安装 Docker | Docker 从入门到实践https://vuepress.mirror.docker-practice.com/install/ 安装Docker 卸载旧版本,安装依赖包,添加yum软件源,更新 yum 软件源缓存,安装 docker-ce…

H3CNE-6-ICMP数据包分析

ICMP:Internet Control Message Protocol ICMP用来传递差错、控制、查询等信息 Wireshark抓包 Wireshark下载国内镜像 ICMP数据包格式 Type:表示ICMP消息类型 Code:表示同一消息类型中的不同信息 ICMP消息类型和编码类型 ICMP应用 &…

如何在Ubuntu上安装NVIDIA显卡驱动并禁止自动更新

在Ubuntu上安装NVIDIA显卡驱动后,有时为了避免兼容性问题或驱动稳定性问题,可能需要禁止自动更新显卡驱动。本文将逐步介绍如何在Ubuntu上安装NVIDIA显卡驱动,并配置系统以禁止驱动的自动更新。 1. 准备工作 在开始之前,请确保你…

世界上首位AI程序员诞生,AI将成为人类的对手吗?

3月13日,世界上第一位AI程序员Devin诞生,不仅能自主学习新技术,自己改Bug,甚至还能训练和微调自己的AI模型,表现已然远超GPT-4等“顶流选手”。 AI的学习速度如此之快,人类的教育能否跟上“机器学习”的速…

云界洞见:移动云服务开启技术创新与问题解决的新篇章

一、什么是移动云 移动云以“央企保障、安全智慧、算网一体、属地服务”为品牌支撑,聚焦智能算力建设,打造一朵智能、智慧、安全可信可控的云,提供更优质的算力服务,引领云计算产业发展。 那么下面博主带领大家了解移动云的优势所…

RS8557XF功能和参数介绍及PDF资料

RS8557XF是一款单通道精密运算放大器,其主要特点包括高精度、低偏移电压、低输入偏置电流和低噪声。以下是该产品的部分参数和功能介绍: 增益带宽积 (GBW): 4.3 MHz,这使得该运放适用于较宽频率范围内的信号处理。 输入偏置电流: 650 μA&…

javas-core VS java-object-diff

对照工具选择 javas-core 和 java-object-diff ,对比demo https://github.com/kofgame/objectdiff-vs-javers,都为同源对比,都支持嵌套对象。 使用JMH测试方法进行性能测试,使用题库的QuestionResponseVO对象来进行对照对比,进行…

Mycat+Mysql搭建数据集群实现数据分片存储

前言 MyCAT介绍 * 一个彻底开源的,面向企业应用开发的“大数据库集群”; * 支持事务、ACID、可以替代MySQL的加强版数据库; * 一个可以视为“MySQL”集群的企业级数据库,用来替代昂贵的Oracle集群; * 一个融合内存缓存技术、Nosql技术、HDFS大数据的新型SQL; * 一个新颖…