当前位置:网站首页>Mysql事务
Mysql事务
2022-07-26 09:15:00 【爱笑的tiger】
1.事务基本介绍
1.1 概念
- 如果一个包含多个步骤的业务操作,被事务管理,要么这些操作同时成功,要么同时失败。
- 事务管理来管理insert,update,delete语句。
- 在mysql数据库中,只有使用了Innodb数据库引擎的数据库或表和才支持实务操作。
1.2 操作
- 开启事务: start transaction;
- 回滚: rollback;
- 提交: commit;
- savepoint identifier; 保存点,可以有多个;
- release savepoint identifier; 删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;
- rollback to identifier; 把事务回滚到标记点;
1.3 案例:转账
CREATE TABLE account (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(10),
money DOUBLE
);
insert into account values(null,'zhangsan',2000),(null,'lisi',2000);
select * from account;
# 张三给李四转账500
# 开启事务
start transaction ;
# 设置保存点,出错了,返回到这个位置
savepoint save_point_b;
# 1.张三账户 -500
update account set money = money - 500 where name='zhangsan';
# 2.李四账户 +500
# 出错了...
update account set money = money + 500 where name='lisi';
# 发现执行没有问题,提交事务
COMMIT;
# 发现出问题了,回滚事务
rollback to save_point_b;
1.4 MySQL数据库中事务默认自动提交
事务提交的两种方式:
自动提交:
* mysql就是自动提交的
* 一条DML(增删改)语句会自动提交一次事务。
手动提交:
* Oracle 数据库默认是手动提交事务
* 需要先开启事务,再提交
修改事务的默认提交方式:
查看事务的默认提交方式:SELECT @@autocommit;
-- 1 代表自动提交 0 代表手动提交
修改默认提交方式: set @@autocommit = 0 禁止自动提交;
2.事务的四大特性ACID
一般来说,事务是必须满足4个条件(ACID):原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性
1. 原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败。
2. 持久性:当事务提交或回滚后,数据库会持久化的保存数据。
3. 隔离性:多个事务之间。相互独立。
4. 一致性:事务操作前后,数据总量不变
3. 事务的隔离级别
3.1 概念
多个事务之间隔离的,相互独立的。但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题。
3.2 存在问题
1. 脏读:一个事务,读取到另一个事务中没有提交的数据
2. 不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。通常针对数据更新(UPDATE)操作。
3. 幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。幻读是针对数据插入(INSERT)操作来说的。
3.3 隔离级别
1. read uncommitted:读未提交
产生的问题:脏读、不可重复读、幻读
2. read committed:读已提交 (Oracle)
产生的问题:不可重复读、幻读
3. repeatable read:可重复读 (MySQL默认)
产生的问题:幻读
4. serializable:串行化
可以解决所有的问题
- 注意:隔离级别从小到大安全性越来越高,但是效率越来越低
- 数据库设置隔离级别:
- set global transaction isolation level 级别字符串;
- 数据库查询隔离级别:
- select @@tx_isolation;
3.4 案例
select @@tx_isolation; 查看默认的事务隔离级别
修改默认的配置文件中的(全部修改my.ini)
transaction-isolation = 隔离级别;
#命令行修改隔离级别;
修改隔离级别的语句是:set [作用域] transaction isolation level [事务隔离级别],
SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}。
set global transaction isolation level read uncommitted;
start transaction;
-- 转账操作
update account set money = money - 500 where id = 1;
update account set money = money + 500 where id = 2;
小结:不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表。
4.案例测试 (隔离级别)
1. read uncommitted:读未提交
设置A,B两个事务为手动提交,隔离级别为read uncommitted;
#1、设置全局隔离级别,打开新控制台,并设置事务手动提交
set global transaction isolation level read uncommitted;
#2.A事务
start transaction;
# 1.张三账户 -500
update account set money = money + 500 where name='zhangsan';
# 2.李四账户 +500
update account set money = money - 500 where name='lisi';
#3.B事务
select * from account;
#4.A事务
rollback;
#5.B事务
select * from account;
两次执行结果:


问题:出现了脏读,不可重复读的情况
2. read committed:读已提交 (Oracle)
更改A,B隔离级别为read committed
#1、设置全局隔离级别,打开新控制台,并设置事务手动提交
set global transaction isolation level read committed;
#2.A事务
start transaction;
# 1.张三账户 -500
update account set money = money - 500 where name='zhangsan';
# 2.李四账户 +500
update account set money = money + 500 where name='lisi';
#3.B事务
select * from account;
#4.A事务
commit;
#5.B事务
select * from account;
运行结果:


发现问题:不可重复读
3. repeatable read:可重复读 (MySQL默认)
更改A,B隔离级别为repeatable read
#1、设置全局隔离级别,打开新控制台,并设置事务手动提交
set global transaction isolation level repeatable read;
#2.A事务
start transaction;
# 1.张三账户 -500
update account set money = money - 500 where name='zhangsan';
# 2.李四账户 +500
update account set money = money + 500 where name='lisi';
#3.B事务
select * from account;//读到未转钱的状态
#4.A事务
commit;
#5.B事务
select * from account;//读到未转钱的状态
两次执行结果:


解决了脏读和不可重复读的情况
4. serializable:串行化
更改A,B隔离级别为serializable
#1、设置全局隔离级别,打开新控制台,并设置事务手动提交
set global transaction isolation level read serializable;
#2、启动两个事务,分别为事务A和事务B,在事务A中使用 update 语句,修改 dname 的值为"国防部"在执行完 update 语句之后,在事务B中查询 dept 表,会看到 dname 的值已经是 "国防部" 了,这时候事务A还没有提交,而此时事务B有可能拿着已经修改过的danem=“国防部” 去进行其他操作了。在事务B进行操作的过程中,很有可能事务A由于某些原因,进行了事务回滚操作,那其实事务B得到的就是脏数据了,拿着脏数据去进行其他的计算,那结果肯定也是有问题的。
#3、执行语句
start transaction;
# 1.张三账户 -500
update account set money = money - 500 where name='zhangsan';
# 2.李四账户 +500
update account set money = money + 500 where name='lisi';
#4、
B事务
select * from account;//直接阻塞,等待A事务结束
#5、
A事务
commit;
#6、
B事务
select * from account;//正常显示
串行化是4种事务隔离级别中隔离效果最好的,解决了脏读、可重复读、幻读的问题,但是效果最差,它将事务的执行变为顺序执行,与其他三个隔离级别相比,它就相当于单线程,后一个事务的执行必须等待前一个事务结束。
边栏推荐
- MySQL strengthen knowledge points
- JS closure: binding of functions to their lexical environment
- PHP 之 Apple生成和验证令牌
- unity TopDown角色移动控制
- 【Mysql】Mysql锁详解(三)
- Pat grade a a1076 forwards on Weibo
- ext3文件系统的一个目录下,无法创建子文件夹,但可以创建文件
- volatile 靠的是MESI协议解决可见性问题?(下)
- Uploading pictures on Alibaba cloud OSS
- 围棋智能机器人阿法狗,阿尔法狗机器人围棋
猜你喜欢
随机推荐
2B and 2C
Rocky基础练习题-shell脚本2
tornado之多进程服务
756. 蛇形矩阵
NPM add source and switch source
服务器内存故障预测居然可以这样做!
760. 字符串长度
布隆过滤器
Node-v download and application, ES6 module import and export
756. Serpentine matrix
李沐d2l(六)---模型选择
839. 模拟堆
“No input file specified “问题的处理
The Child and Binary Tree-多项式开根求逆
Summary of common activation functions for deep learning
Form form
Does volatile rely on the MESI protocol to solve the visibility problem? (next)
jvm命令归纳
【Mysql】Mysql锁详解(三)
Hbuilderx runs the wechat developer tool "fail to open ide" to solve the error









