事务

事务

目录
  • 事务
    • 1. 什么是事务
    • 2. 事务原则:ACID原则
      • 1. 原子性(Atomicity)
      • 2. 一致性(Consistency)
      • 3. 隔离性(isolation)
      • 4. 持久性(durability)
      • 5. 隔离所导致的一些问题
        • 1. 脏读
        • 2. 不可重复读
        • 3. 幻读(虚读)
    • 3. 执行事务
    • 4. 模拟场景

1. 什么是事务

要么都成功,要么都失败


  1. SQL执行:A给B转账 A 1000 --> 200 B 200
  2. SQL执行:B收到A的钱 A 800 --> B 400

将一组SQL放在一个批次中去执行

2. 事务原则:ACID原则

1. 原子性(Atomicity)

针对同一个事务

事务_第1张图片

这个过程包含两个步骤

A: 800 - 200 = 600

B: 200 + 200 = 400

原子性表示,这两个步骤一起成功,或者一起失败,不能只发生其中一个动作

2. 一致性(Consistency)

针对一个事务操作前与操作后的状态一致

事务_第2张图片

操作前A:800,B:200

操作后A:600,B:400

一致性表示事务完成后,符合逻辑运算

事务前后的数据完整性要保持一致

3. 隔离性(isolation)

针对多个用户同时操作,主要是排除其他事务对本次事务的影响

事务_第3张图片

两个事务同时进行,其中一个事务读取到另外一个事务还没有提交的数据,B
事务_第4张图片

4. 持久性(durability)

表示事务结束后的数据不随着外界原因导致数据丢失

操作前A:800,B:200

操作后A:600,B:400

如果在操作前(事务还没有提交)服务器宕机或者断电,那么重启数据库以后,数据状态应该为

A:800,B:200

如果在操作后(事务已经提交)服务器宕机或者断电,那么重启数据库以后,数据状态应该为

A:600,B:400

事务没有提交:恢复到原状

事务已经提交:持久化到数据库

事务一旦提交就不可逆

5. 隔离所导致的一些问题

1. 脏读

值一个事务读取了另外一个事务未提交的数据

2. 不可重复读

在一个事务内读取表中的某一行数据,多次读取结果不同。(这个不一定是错误,只是在某些场合不对)

3. 幻读(虚读)

是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致

3. 执行事务

graph TB id1(关闭自动提交)-->id2(开启一个事务) id2-->id3(成功) id2-->id4(回滚) id3-->id5(开启自动提交) id4-->id1
-- ======================  事务  =======================
set autocommit = 0	-- 关闭事务
set autocommit = 1	--  开启事务(默认的)

-- 手动处理事务
set autocommit = 0	-- 关闭自动提交

-- 事务开启
start transaction	-- 标记一个事务的开始,从这个之后的SQL都在同一个事务内

insert into XXX
insert into XXX

-- 提交:持久化(成功!)
commit
-- 回滚:回到原来的样子(失败!)
rollback

-- 事务结束
set auto_commit = 1	-- 开启自动提交

-- 了解
savepoint 保存点的名称	-- 设置一个事务的保存点
rollback to savepoint 保存点的名称	-- 回滚到保存点
release savepoint 保存点的名称	-- 撤销保存点

4. 模拟场景

模拟转账的

-- 转账
create database shop character set utf8 collate utf8_general_ci
use shop

create table `account` (
  `id` int(3) not null auto_increment,
  `name` varchar(30) not null,
  `money` decimal(9,2) not null,
  primary key (`id`)
)engine=innodb default charset=utf8

insert into `account` (`name`,`money`) values
('A',2000.00),
('B',10000.00)

-- 模拟转账:事务
set autocommit = 0;	-- 关闭自动提交
start transaction;	-- 开启一个事务(后面的是一组事务)

update `account` set `money` = `money` - 500
where `name` = 'A'	-- A减500
update `account` set `money` = `money` + 500
where `name` = 'B'	-- B加500

commit;			-- 提交事务,就被持久化了!
rollback;		-- 回滚,持久化后无法回滚!

set autocommit = 1;	-- 恢复默认值

你可能感兴趣的:(事务)