石小疯 发表于 2024-6-15 03:33:47

MySQL-----变乱(详解)

目次
一.变乱简介:
二.变乱操纵:
未控制变乱:
变乱的控制方法一:
 变乱的控制方法二:
 三:变乱的四大特性:
四.并发变乱问题:
五.变乱的隔离级别:

一.变乱简介:

变乱 是一组操纵的集合,它是一个不可分割的工作单元,变乱会把所有的操纵作为一个整体一起向系 统提交或撤销操纵哀求,即这些操纵要么同时乐成,要么同时失败。
比如,银行转账的操纵就是一个典型的变乱问题,举个例子:张三给李四转账1000块钱,张三银行账户的钱减少1000,而李四银行账户的钱要增加 1000。 这一组操纵就必须在一个变乱的范围内,要么都乐成,要么都失败。
https://img-blog.csdnimg.cn/direct/fbe7f78ac7b84b55995691db01877f54.png
正常情况: 转账这个操纵, 需要分为以下这么三步来完成 , 三步完成之后, 张三减少1000, 而李四 增加1000, 转账乐成 :
https://img-blog.csdnimg.cn/direct/f724c9bd94dd46caa135775da7e8e068.png
异常情况: 转账这个操纵, 也是分为以下这么三步来完成 , 在执行第三步是报错了, 如许就导致张 三减少1000块钱, 而李四的金额没变, 如许就造成了数据的不一致, 就出现问题了:
 https://img-blog.csdnimg.cn/direct/91b080aaca1b41629ae01bd5fc8f582e.png
为相识决上述的问题,就需要通过数据的变乱来完成,我们只需要在业务逻辑执行之前开启变乱,执行 完毕后提交变乱。如果执行过程中报错,则回滚变乱,把数据恢复到变乱开始之前的状态:
https://img-blog.csdnimg.cn/direct/015f50daa428436f9b0c84106489c5dd.png
   注意: 默认MySQL的变乱是主动提交的,也就是说,当执行完一条DML语句时,MySQL会立即隐式的提交变乱。
由于MySQL的变乱主动提交的这种特性,就要求我们将设置修改为手动变乱,以此来发现问题并且办理问题。
二.变乱操纵:

未控制变乱:



[*]数据准备(这里我们根据上面的例子来分析问题):
# 数据准备
drop table if exists account;

create table account(
id int primary key auto_increment comment 'ID',
name varchar(10) comment'年龄',
money double(10,2) comment '余额'
)comment '账户表';

insert into account(name,money) values('张三',2000),('李四',2000); https://img-blog.csdnimg.cn/direct/3313ddff1aac41de915592d396b67f49.png
1).测试正常情况:
# 未控制事务

-- 1.查询张三余额
select * from account where name = '张三';

-- 2.张三的余额减少1000
update account set money = money - 1000 where name = '张三';

-- 3.李四的余额增加1000
update account set money = money + 1000 where name = '李四'; 运行结果:
https://img-blog.csdnimg.cn/direct/f209e53ab7984ed8abf1a30f9adb802a.png 2).异常情况(执行前要先将数据回复原样):
-- 将数据回复原样
update account set money = 2000 where name = '张三' or name = '李四';

-- 1.查询张三余额
select * from account where name = '张三';

-- 2.张三的余额减少1000
update account set money = money - 1000 where name = '张三';

事务异常…… -- 异常情况,第三条SQL语句不会执行

-- 3.李四的余额增加1000
update account set money = money + 1000 where name = '李四'; 我们把数据都恢复到2000, 然后再次一次性执行上述的SQL语句(出错了.... 这句话不符合SQL语 法,执行就会报错),查抄终极的数据情况, 发现数据在操纵前后不一致了。 
执行结果:
https://img-blog.csdnimg.cn/direct/7bb18afc1f1648cbae9881dfdaa5b4da.png
为相识决如许的问题,我们引入变乱的控制方法:
变乱的控制方法一:

# 事务的控制方式一:

1). 查看/设置事务提交方式
SELECT @@autocommit ;-- 查看事务的提交方式
                     -- 1 为事务自动提交,0为事务手动提交

SET @@autocommit = 0 ;-- 修改事务的提交方式

2). 提交事务
COMMIT;

3). 回滚事务
ROLLBACK; 详细实现:
-- 1). 查看/设置事务提交方式
select @@autocommit ; -- 1 为事务自动提交,0为事务手动提交
set @@autocommit = 0 ;-- 将事务设置为手动提交

-- 1.查询张三余额
select * from account where name = '张三';

-- 2.张三的余额减少1000
update account set money = money - 1000 where name = '张三';

-- 3.李四的余额增加1000
update account set money = money + 1000 where name = '李四';

-- 2). 提交事务
commit;

-- 3). 回滚事务
rollback;  注意:上述的这种方式,我们只是修改了变乱的主动提交活动, 把默认的主动提交修改为了手动提 交, 此时我们执行的DML语句都不会提交, 只有执行到commit之后才会完成提交。
 变乱的控制方法二:

# 事务的控制方法二:

1). 开启事务
START TRANSACTION 或 BEGIN ;

2). 提交事务
COMMIT;

3). 回滚事务
ROLLBACK 详细实现:
# 控制事务的方式二:--->控制之前要设置为自动提交
SET @@autocommit = 1 ;

-- 1). 开启事务
start transaction;

-- 1.查询张三余额
select * from account where name = '张三';

-- 2.张三的余额减少1000
update account set money = money - 1000 where name = '张三';

-- 3.李四的余额增加1000
update account set money = money + 1000 where name = '李四';

-- 2). 提交事务
commit;

-- 3). 回滚事务
rollback;  三:变乱的四大特性:

   

[*] 原子性(Atomicity):变乱是不可分割的最小操纵单元,要么全部乐成,要么全部失败。
[*]一致性(Consistency):变乱完成时,必须使所有的数据都保持一致状态。
[*]隔离性(Isolation):数据库体系提供的隔离机制,包管变乱在不受外部并发操纵影响的独立 情况下运行。
[*]长期性(Durability):变乱一旦提交或回滚,它对数据库中的数据的改变就是永世的。

上面四个属性,可以简称为 ACID 。
原子性(Atomicity,或称不可分割性)
一致性(Consistency)
隔离性(Isolation,又称独立性)
长期性(Durability)。
四.并发变乱问题:



[*] 赃读:一个变乱读到另外一个变乱还没有提交的数据。https://img-blog.csdnimg.cn/direct/a3a5a2d220b04a259950ff30725f7a4a.png
[*] 不可重复读:一个变乱先后读取同一条记录,但两次读取的数据差别,称之为不可重复读。 
 https://img-blog.csdnimg.cn/direct/0eedc0dc07c642078e2ab7a178b01489.png


[*]幻读:一个变乱按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据 已经存在,似乎出现了 "幻影"。 
https://img-blog.csdnimg.cn/direct/1050a5f2fa87449b918ad83c880761e1.png
五.变乱的隔离级别:

为相识决并发变乱所引发的问题,在数据库中引入了变乱隔离级别。主要有以下几种: 
https://img-blog.csdnimg.cn/direct/e0899e82166e4021aa43feff78c799c1.png
注意:X体现该级别已经办理了对应问题,√ 体现该级别没有办理这个问题
   读未提交【Read Uncommitted】: 在该隔离级别,所有的变乱都可以看到其他变乱没有提交的执行结果。(实际生产中不大概使用这种隔离级别的),但是相当于没有任何隔离性,也会有很多并发问题,如脏读,幻读,不可重复读等.
读提交【Read Committed】:该隔离级别是大多数数据库的默认的隔离级别(不是 MySQL 默认的)。它满足了隔离的简单定义:一个变乱只能看到其他的已经提交的变乱所做的改变。这种隔离级别会引起不可重复读,即一个变乱执行时,如果多次 select,大概得到差别的结果。
可重复读【Repeatable Read】: 这是 MySQL 默认的隔离级别,它确保同一个变乱,在执行中,多次读取操纵数据时,会看到同样的数据行。但是有的数据库会有幻读问题。(MySQL不会)
串行化【Serializable】: 这是变乱的最高隔离级别,它通过欺压变乱排序,使之不大概相互冲突,从而办理了幻读的问题。它在每个读的数据行上面加上共享锁。但是大概会导致超时和锁竞争(这种隔离级别太极端,实际生产基本不使用)
详细操纵:
-- 1). 查看事务隔离级别
SELECT @@TRANSACTION_ISOLATION;

-- 2). 设置事务隔离级别
SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED |
READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
注意:变乱隔离级别越高,数据越安全,但是性能越低。 
结语: 写博客不但仅是为了分享学习履历,同时这也有利于我巩固知识点,总结该知识点,由于作者水平有限,对文章有任何问题的还请指出,接受各人的批评,让我改进。同时也希望读者们不吝啬你们的点赞+收藏+关注,你们的鼓励是我创作的最大动力!
https://img-blog.csdnimg.cn/direct/625b2da36b874856a25ba388069de9a4.gif

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: MySQL-----变乱(详解)