【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.总结

相关推荐
lucky_syq1 小时前
再谈向量数据库:AI时代的存储新引擎
大数据·数据库·人工智能
v***44671 小时前
【Mysql】:如何恢复误删的数据?
数据库·mysql
x***01061 小时前
使用 MySQL 从 JSON 字符串提取数据
mysql·oracle·json
b***67642 小时前
使用 Canal 实时从 MySql 向其它库同步数据
数据库·mysql
2501_941111372 小时前
Django全栈开发入门:构建一个博客系统
jvm·数据库·python
b***9102 小时前
在linux(Centos)中Mysql的端口修改保姆级教程
linux·mysql·centos
枫叶丹42 小时前
【Qt开发】Qt窗口(二) -> QToolBar工具栏
开发语言·数据库·c++·qt
l1t2 小时前
利用DuckDB列表一句SQL输出乘法口诀表
数据库·sql·算法·duckdb
q***99632 小时前
SQL 中 COUNT 的用法详解
数据库·sql