【MySQL | 基础】事务

前文回顾:多表查询

1.事务简介

2.事务操作

[2.1 准备数据表:](#2.1 准备数据表:)

[2.2 演示转账操作](#2.2 演示转账操作)

[2.3 演示在中间出现异常的情况并引出事务](#2.3 演示在中间出现异常的情况并引出事务)

[2.3.1 设置手动提交事务 / 回滚](#2.3.1 设置手动提交事务 / 回滚)

[2.3.2 不修改提交事务的方式,使用开启事务](#2.3.2 不修改提交事务的方式,使用开启事务)

[3. 事务的四大特性 ACID(面试题)](#3. 事务的四大特性 ACID(面试题))

[4. 并发事务引发的问题](#4. 并发事务引发的问题)

5.事务隔离基本​编辑

6.总结​编辑


1.事务简介

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

案例:银行转账,如果转账过程中的操作有一步是抛出异常整个转账流程失败,让后事务回滚 恢复抛异常之前的操作。

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

2.事务操作

2.1 准备数据表:

sql 复制代码
create table account(
  id int auto_increment primary key comment '主键id',
  name varchar(10) comment '姓名',
  money int comment'余额'
)comment '账户表';

INSERT INTO account (id, NAME, money)
VALUES
(NULL, '张三', 2000),
(NULL, '李四', 2000)

select * from account;
-- 数据恢复,方便后面操作
update account set money = 2000 where name = '张三' or name = '李四';

2.2 演示转账操作

sql 复制代码
-- 转账操作(张三转给李四1000)
-- 1、查询张三账户的余额
select * from account where name = '张三';

-- 2、将张三账户的余额-1000
update account
set money =
case
  when money > 1000 then
    money - 1000
  else
    money
end
where name = '张三';  


-- 3、将李四账户的余额+1000
update account set money = money + 1000 where name = '李四';

2.3 演示在中间出现异常的情况并引出事务

上面 2.2 的代码是完全不会抛出异常的,因为我们要演示事务并引出事务的语法,所以我们在代码步骤三之前让程序抛出异常提前结束。执行观察出现的情况。

sql 复制代码
-- 数据恢复,方便后面操作
update account set money = 2000 where name = '张三' or name = '李四';

-- 转账操作(张三转给李四1000)
-- 1、查询张三账户的余额
select * from account where name = '张三';

-- 2、将张三账户的余额-1000
update account
set money =
case
  when money > 1000 then
    money - 1000
  else
    money
end
where name = '张三';  

程序抛出异常
-- 3、将李四账户的余额+1000
update account set money = money + 1000 where name = '李四';

选中上面的代码执行后发现抛出异常,数据表的结果如下:

分析:一开始"张三"和"李四"都有"两千元"的余额,将"张三"的 一千元 转账给"李四",结果"张三"的账户减去的 一千 但是"李四"并没有加上"张三"转的 一千,这显然是出现了bug。那么我们怎么解决这一问题。我们需要将转账操作整个流程控制一个事务中。

MySQL中的事务是默认提交。可以认为"一条语句就是一个自动提交的事务",但严格来说,是"每条语句被自动包装在一个事务中并立即提交"。

那么我们怎么来控制事务。这就需要使用下面我们学习到的语句来设置事务提交方式为手动提交。

2.3.1 设置手动提交事务 / 回滚

  • 看 / 设置事务提交方式

SELECT @@autocommit; -- 查看事务提交方式

SET @@autocommit = 0;

  • 提交事务

COMMIT;

  • 回滚事务

ROLLBACK;

代码演示

sql 复制代码
SELECT @@autocommit; -- 结果为1 代表当前事务自动提交
set @@autocommit = 0; -- 设置成手动提交

-- 转账操作(张三转给李四1000)
-- 1、查询张三账户的余额
select * from account where name = '张三';

-- 2、将张三账户的余额-1000
update account
set money =
case
  when money > 1000 then
    money - 1000
  else
    money
end
where name = '张三';  

程序执行异常...
-- 3、将李四账户的余额+1000
update account set money = money + 1000 where name = '李四';

-- 提交事务
commit;

-- 回滚事务
rollback;

上面代码执行转账操作,如果抛出异常我们可以执行回滚事务 rollback 语句,则会将事务中所有未提交的更改撤销,恢复到事务开始前的状态(保证了数据库当中数据的正确性)。如果没有抛出异常可以执行提交事务 commit语句。

2.3.2 不修改提交事务的方式,使用开启事务

  • 开启事务

START TRANSACTION 或 BEGIN;

  • 提交事务

COMMIT;

  • 回滚事务

ROLLBACK;

代码演示

sql 复制代码
-- 方式2 不修改提交事务的方式
-- 转账操作(张三转给李四1000)
-- 开始事务
START TRANSACTION -- 或者 
BEGIN
-- 1、查询张三账户的余额
select * from account where name = '张三';

-- 2、将张三账户的余额-1000
update account
set money =
case
  when money > 1000 then
    money - 1000
  else
    money
end
where name = '张三';  

程序执行异常...
-- 3、将李四账户的余额+1000
update account set money = money + 1000 where name = '李四';

-- 提交事务
commit;

-- 回滚事务
rollback;

3. 事务的四大特性 ACID(面试题)

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

4. 并发事务引发的问题

  • 是指 A 事务和 B事务(或者多个事务)同时操作同一个数据库或者同一张表所引发的问题。

|-------|-------------------------------------------------------|
| 问题 | 描述 |
| 脏读 | 一个事务读到另一个事务还没有提交的数据 |
| 不可重复读 | 一个事务先后读取同一条记录,但是两次读取数据不同,称为不可重复读。 |
| 幻读 | 一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据的,又发现这行数据已经存在,好像出现了"幻影" |

5.事务隔离基本

6.总结

相关推荐
计算机毕设VX:Fegn08952 小时前
计算机毕业设计|基于springboot + vue医院设备管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
Mr__Miss2 小时前
保持redis和数据库一致性(双写一致性)
数据库·redis·spring
Knight_AL3 小时前
Spring 事务传播行为 + 事务失效原因 + 传播行为为什么不用其他模式
数据库·sql·spring
倔强的石头_3 小时前
时序数据时代的“存储与分析困局”解析及金仓解决方案
数据库
计算机毕设VX:Fegn08953 小时前
计算机毕业设计|基于springboot + vue小型房屋租赁系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
倔强的石头_4 小时前
场景化落地指南——金仓时序数据库在关键行业的应用实践
数据库
SelectDB4 小时前
驾驭 CPU 与编译器:Apache Doris 实现极致性能的底层逻辑
运维·数据库·apache
刀法如飞4 小时前
开箱即用的 DDD(领域驱动设计)工程脚手架,基于 Spring Boot 4.0.1 和 Java 21
java·spring boot·mysql·spring·设计模式·intellij-idea
zbguolei4 小时前
MySQL根据身份证号码计算出生日期和年龄
数据库·mysql
马克学长5 小时前
SSM校园图书借阅服务系统jd2z8(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·图书管理系统·ssm 框架·ssm 校园图书借阅系统