事务
目录
- 事务
- 1. 什么是事务
- 2. 事务原则:ACID原则
- 1. 原子性(Atomicity)
- 2. 一致性(Consistency)
- 3. 隔离性(isolation)
- 4. 持久性(durability)
- 5. 隔离所导致的一些问题
- 1. 脏读
- 2. 不可重复读
- 3. 幻读(虚读)
- 3. 执行事务
- 4. 模拟场景
1. 什么是事务
要么都成功,要么都失败
- SQL执行:A给B转账 A 1000 --> 200 B 200
- SQL执行:B收到A的钱 A 800 --> B 400
将一组SQL放在一个批次中去执行
2. 事务原则:ACID原则
1. 原子性(Atomicity)
针对同一个事务
这个过程包含两个步骤
A: 800 - 200 = 600
B: 200 + 200 = 400
原子性表示,这两个步骤一起成功,或者一起失败,不能只发生其中一个动作
2. 一致性(Consistency)
针对一个事务操作前与操作后的状态一致
操作前A:800,B:200
操作后A:600,B:400
一致性表示事务完成后,符合逻辑运算
事务前后的数据完整性要保持一致
3. 隔离性(isolation)
针对多个用户同时操作,主要是排除其他事务对本次事务的影响
两个事务同时进行,其中一个事务读取到另外一个事务还没有提交的数据,B
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; -- 恢复默认值