数据库(DataBase)-事务详解及案例解析

6.事务

1.什么是事务

事务就是将一组SQL语句放在同一批次内去执行

如果一个SQL语句出错,则该批次内的所有SQL都将被取消执行

MySQL事务处理只支持InnoDB和BDB数据表类型

特点:要么都成功,要么都失败。

情景分析:


1.Sql执行:成龙龙给成果果转钱, 成龙龙 777 —> 77 给成果果 700

2.Sql执行:成果果接到成龙龙的钱, 成龙龙 700 <—> 成果果 777


两个Sql语句放在一起执行,一个批次进行执行,一成全成,一败全败。

2.事务的原则:ACID

(1)原子性(Atomicity)

一批次的操作,要么一起成功,要么一起失败。

整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(ROLLBACK)到事务开始前的状态,就像这个事务从来没有执行过一样。

(2)一致性(Consistency)

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

一个事务可以封装状态改变(除非它是一个只读的)。事务必须始终保持系统处于一致的状态,不管在任何给定的时间并发事务有多少。也就是说:如果事务是并发多个,系统也必须如同串行事务一样操作。其主要特征是保护性和不变性(Preserving an Invariant),以转账案例为例,Eg:成龙和成果一共有777+700元,转账前后,都是如此,金额总数不变。

(3)隔离性(Isolation)

事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。

隔离所导致的一些问题:

脏读

一个事务读取了另外一个事务没有提交的数据。

不可重复读取

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

虚读(幻读)

是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。(一般是行影响,多了一行)

(4)持久性(Durability)

事务一单提交就不可逆了,被持久化到数据库里。

1.事务没有提交,就恢复到原状态。

2.事务一旦提交,就持久化到数据库。

3.执行事务

执行事务的流程和基本语法:

-- MySQL是默认开启事务自动提交的,咱们学习时,可以先关闭。
set autocommit = 0; -- 关闭事务
set autocommit = 1; -- 开启事务,开启是默认的

-- 手动处理事务
set autocommit = 0; -- 关闭事务

-- 事务开始:
start transaction;
-- 标记一个事务的开始,从这个代码之后的sql都在同一个事务里面

-- 提交:实现持久化。(成功的话)
commit;

-- 回滚:返回原来的样子。(失败的话)
rollback;

-- 事物结束,重新开启。
set autocommit = 1; -- 开启事务,开启是默认的

-- 了解:设置事务的保存点,就像游戏里的存档点。
savepoint 保存点名;

-- 回滚至保存点:就像游戏里死后的返回上一个存档点。
rollback to savepoint 保存点名;

-- 撤销保存点:
release savepoint 保存点名;

模拟场景:

转账练习:创建数据库和表格。

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;

/*
mysql字段decimal(9,2)中9是定点精度,2是小数位数。
存在这么一个公式:decimal(a,b)。
其中a指定指定小数点左边和右边可以存储百的十进度制数字的最大个数,最大精度38;
b指定小数点右边可以存储的十进制数字的最大个数,小数位数必须是从 0 到 a之间的值,
默认小数位数是 0。
*/

insert into account(`name`,`money`) values
('成果果','7777'),
('成龙龙','70000');

在这里插入图片描述

模拟转账:事务处理

-- 关闭自动提交。
set autocommit = 0;

-- 开启一个事务。
start transaction;

-- 关闭安全模式,防止无法删改数据等。
SET SQL_SAFE_UPDATES = 0;

-- 成果果减去777元
update account set money = money - 777 where `name` = '成果果';

-- 成龙龙接收777元。
update account set money = money + 777 where `name` = '成龙龙';

-- 判断成功,提交。
commit;

-- 判断失败,回滚。
rollback;

-- 开启安全模式,
SET SQL_SAFE_UPDATES = 1;

-- 恢复默认值,恢复自动提交。
set autocommit = 1;

成功修改后:

在这里插入图片描述

执行rollback:

在这里插入图片描述

执行commit:

在这里插入图片描述

且无法再次修改为原来的样子。

参考文献

《【狂神说Java】MySQL最新教程通俗易懂》
视频连接:https://www.bilibili.com/video/BV1NJ411J79W
《狂神说MySQL06:事务和索引》
原文连接

2020.05.17

原创文章 19 获赞 20 访问量 712

猜你喜欢

转载自blog.csdn.net/weixin_44199123/article/details/106180514
今日推荐