数据库造神计划第十八天---事务(1)

🔥个人主页: 寻星探路

🎬作者简介:Java研发方向学习者

📖个人专栏:、《

⭐️人生格言:没有人生来就会编程,但我生来倔强!!!


​


目录

一、什么是事务?

二、事务的ACID特性

三、为什么要使用事务?

四、如何使用事务

1、查看支持事务的存储引擎

2、语法

3、开启⼀个事务,执行修改后回滚

4、开启⼀个事务,执行修改后提交

5、保存点

6、自动/手动提交事务


一、什么是事务?

事务把⼀组SQL语句打包成为⼀个整体,在这组SQL的执行过程中,要么全部成功,要么全部失败。这组SQL语句可以是⼀条也可以是多条。来看⼀个转账的例子,如图:

在这个例子中,涉及了两条更新语句:

sql 复制代码
# ================账户表====================
CREATE TABLE `bank_account`  (
`id` bigint PRIMARY KEY AUTO_INCREMENT, 
`name` varchar(255) NOT NULL,     # 姓名
`balance` decimal(10, 2) NOT NULL # 余额
);

INSERT INTO bank_account(`name`, balance) VALUES('张三', 1000);
INSERT INTO bank_account(`name`, balance) VALUES('李四', 1000);

# ================更新操作===================
# 张三余额减少100
UPDATE bank_account set balance = balance - 100 where name = '张三';
# 李四余额增加100
UPDATE bank_account set balance = balance + 100 where name = '李四';

如果转账成功,应该有以下结果:

(1)张三的账⼾余额减少100 ,变成 900 ,李四的账户余额增加了100,变成1100 ,不能出现张三的余额减少而李四的余额没有增加的情况;

(2)张三和李四在发生转账前后的总额不变,也就是说转账前张三和李四的余额总数为1000+1000=2000 ,转账后他们的余额总数为 900+1100=2000 ;

(3)转账后的余额结果应当保存到存储介质中,以便以后读取;

(4)还有一点需要要注意,在转账的处理过程中张三和李四的余额不能因其他的转账事件而受到干扰; 以上这四点在事务的整个执行过程中必须要得到保证,这也就是事务的 ACID 特性

数据库的事务,是用来解决"原子性"问题的~~

原子:不可拆分的最小单位~~

二、事务的ACID特性

事务的ACID特性指的是Atomicity (原子性), Consistency(一致性), Isolation (隔离性)和Durability (持久性)。

• Atomicity (原子性):⼀个事务中的所有操作,要么全部成功 ,要么全部失败,不会出现只执行了⼀半的情况,如果事务在执行过程中发生错误,会回滚( Rollback )到事务开始前的状态,就像这个事务从来没有执行过⼀样;

• Consistency (一致性):在事务开始之前和事务结束以后,数据库的完整性不会被破坏。这表示写入的数据必须完全符合所有的预设规则,包括数据的精度、关联性以及关于事务执⾏过程中服务器崩溃后如何恢复;

• Isolation (隔离性):**数据库允许多个并发事务同时对数据进行读写和修改,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不⼀致。**事务可以指定不同的隔离级别,以权衡在不 同的应用场景下数据库性能和安全;

• Durability (持久性):事务处理结束后,对数据的修改将永久的写⼊存储介质,即便系统故障 也不会丢失。

三、为什么要使用事务?

事务具备的ACID特性,是我们使用事务的原因,在我们日常的业务场景中有大量的需求要用事务来保证。支持事务的数据库能够简化我们的编程模型,不需要我们去考虑各种各样的潜在错误和并发问题,在使⽤事务过程中,要么提交,要么回滚,不用去考虑网络异常,服务器宕机等其他因素,因此我们经常接触的事务本质上是数据库对 ACID 模型的⼀个实现,是为应用层服务的。

四、如何使用事务

1、查看支持事务的存储引擎

要使用事务那么数据库就要支持事务,在MySQL中支持事务的存储引擎是InnoDB,可以通过 show engines; 语句查看:

2、语法

通过以下语句可以完成对事务的控制:

sql 复制代码
# 开始⼀个新的事务
START TRANSACTION;
# 或
BEGIN;

# 提交当前事务,并对更改持久化保存
COMMIT;

# 回滚当前事务,取消其更改
ROLLBACK;

• START TRANSACTION 或BEGIN 的开始⼀个新事务;

• COMMIT 提交当前事务,并对更改持久化保存;

• RO LLBACK 回滚当前事务,取消其更改;

• 无论提交还是回滚,事务都会关闭

3、开启⼀个事务,执行修改后回滚

sql 复制代码
# 开启事务
START TRANSACTION;
# 在修改之前查看表中的数据
select * from bank_account;
sql 复制代码
# 张三余额减少100
UPDATE bank_account set balance = balance - 100 where name = '张三';
# 李四余额增加100 
UPDATE bank_account set balance = balance + 100 where name = '李四';

# 在修改之后,提交之前查看表中的数据,余额已经被修改 
select * from bank_account;
sql 复制代码
# 回滚事务
ROLLBACK;
# 再查询发现修改没有⽣效
select * from bank_account;

4、开启⼀个事务,执行修改后提交

sql 复制代码
# 开启事务
BEGIN;
# 在修改之前查看表中的数据 
select * from bank_account;
sql 复制代码
# 张三余额减少100
UPDATE bank_account set balance = balance - 100 where name = '张三';
# 李四余额增加100 
UPDATE bank_account set balance = balance + 100 where name = '李四';

# 在修改之后,提交之前查看表中的数据,余额已经被修改
select * from bank_account;
sql 复制代码
# 提交事务
COMMIT;

# 再查询发现数据已被修改,说明数据已经持久化到磁盘
select * from bank_account;

5、保存点

在事务执行的过程中设置保存点,回滚时指定保存点可以把数据恢复到保存点的状态

sql 复制代码
# 开启事务
START TRANSACTION;

# 在修改之前查看表中的数据
select * from bank_account;
sql 复制代码
# 张三余额减少100
UPDATE bank_account set balance = balance - 100 where name = '张三';
# 李四余额增加100 
UPDATE bank_account set balance = balance + 100 where name = '李四';

# 在修改之后,提交之前查看表中的数据,余额已经被修改
select * from bank_account;
sql 复制代码
# 设置保存点
SAVEPOINT savepoint1;

# 再次执⾏,张三余额减少100
UPDATE bank_account set balance = balance - 100 where name = '张三';
# 再次执⾏,李四余额增加100
UPDATE bank_account set balance = balance + 100 where name = '李四';

# 余额已经被修改
select * from bank_account;
sql 复制代码
# 设置第⼆个保存点
SAVEPOINT savepoint2;

# 插⼊⼀条新记录
insert into bank_account values (null, '王五', 1000);

# 查询结果,新记录写⼊成功
select * from bank_account;
sql 复制代码
# 回滚到第⼆个保存点 
ROLLBACK TO savepoint2;

# 回滚成功
select * from bank_account;
sql 复制代码
# 回滚到第⼀个保存点
ROLLBACK TO savepoint1;
# 回滚成功
select * from bank_account;
sql 复制代码
# 回滚时不指定保存点,直接回滚到事务开始时的原始状态,事务关闭
ROLLBACK;

# 原始状态
select * from bank_account;

6、自动/手动提交事务

默认情况下,MySQL是自动提交事务的,也就是说我们执行的每个修改操作,比如插入、更新和删除,都会自动开启⼀个事务并在语句执行完成之后自动提交,发⽣异常时自动回滚。

查看当前事务是否自动提交可以使用以下语句

sql 复制代码
show variables like 'autocommit';

可以通过以下语句设置事务为自动或手动提交

sql 复制代码
# 设置事务⾃动提交 
SET AUTOCOMMIT=1;     # ⽅式⼀
SET AUTOCOMMIT=ON;    # ⽅式二
# 设置事务⼿动提交 
SET AUTOCOMMIT=0;     # ⽅式⼀
SET AUTOCOMMIT=OFF;   # ⽅式⼆

注意:

只要使用 START TRANSACTION 或 BEGIN 开启事务,必须要通过 COMMIT 提交才会持久化,与是否设置 SET autocommit 无关。

手动提交模式下,不用显示开启事务,执行修改操作后,提交或回滚事务时直接使用 commit 或 rollback

已提交的事务不能回滚

由于内容较多,会分为多篇讲解,预知后续内容,请看后续博客!!!

相关推荐
wefg15 分钟前
【Redis】安装与启动
数据库·redis·缓存
大圣编蚕30 分钟前
常见的 Redis 面试题(高频整理)
数据库·redis·缓存
派小心.1 小时前
网站统计采样数据的误差核对
大数据·服务器·前端·数据库·人工智能·小程序·数据分析
龙腾AI白云1 小时前
数字孪生、具身智能、世界模型三者交叉
数据库·人工智能·机器学习·flask·pygame
SelectDB技术团队2 小时前
Apache Doris 基于 Lance 的向量检索深度解析
数据库·数据仓库·数据分析·湖仓一体·apache doris·lakehouse·多模湖仓
这个DBA有点耶2 小时前
从INDEX到JOIN_ORDER:MySQL 8.0 Hint语法体系与五类实战场景
数据库·mysql·架构
数字新视界2 小时前
机房动环监控助力智能管理
大数据·服务器·数据库·动环监控系统·动力与环境监控系统
梅菲塔亚2 小时前
博客_Redis入门到实战
数据库·redis·缓存
abcyuu2 小时前
用友 U8 Cloud 生产制造模块深度解析:从 BOM 建立到成本核算的技术实现
前端·数据库·制造
夜雪一千2 小时前
MySQL 的ID用什么数据类型更好?主键ID选型实战
数据库·mysql