首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >数据库造神计划第十八天---事务(1)

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

作者头像
寻星探路
发布2025-12-17 18:42:49
发布2025-12-17 18:42:49
1090
举报
文章被收录于专栏:CSDN博客CSDN博客

一、什么是事务?

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

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

代码语言:javascript
复制
# ================账户表====================
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、语法

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

代码语言:javascript
复制
# 开始⼀个新的事务
START TRANSACTION;
# 或
BEGIN;

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

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

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

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

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

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

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

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

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

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

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

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

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

5、保存点

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

代码语言:javascript
复制
# 开启事务
START TRANSACTION;

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

# 在修改之后,提交之前查看表中的数据,余额已经被修改
select * from bank_account;
代码语言:javascript
复制
# 设置保存点
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;
代码语言:javascript
复制
# 设置第⼆个保存点
SAVEPOINT savepoint2;

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

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

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

# 原始状态
select * from bank_account;

6、自动/手动提交事务

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

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

代码语言:javascript
复制
show variables like 'autocommit';

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

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

注意: 只要使用 START TRANSACTION 或 BEGIN 开启事务,必须要通过 COMMIT 提交才会持久化,与是否设置 SET autocommit 无关。 手动提交模式下,不用显示开启事务,执行修改操作后,提交或回滚事务时直接使用 commit 或 rollback 已提交的事务不能回滚

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-09-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、什么是事务?
  • 二、事务的ACID特性
  • 三、为什么要使用事务?
  • 四、如何使用事务
    • 1、查看支持事务的存储引擎
    • 2、语法
    • 3、开启⼀个事务,执行修改后回滚
    • 4、开启⼀个事务,执行修改后提交
    • 5、保存点
    • 6、自动/手动提交事务
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档