MySQL~事务的概念、特性(ACID)及使用、了解并解决使用事务时可能产生的问题(丢失更新、脏读、不可重复读、幻读)

目录

事物的概念及使用

事物的概念

为什么要使用事务

事务的特性(ACID)

事务的使用

可能产生的问题

丢失更新

脏读

不可重复读

幻读

如何解决使用事务时产生的问题?


事物的概念及使用

事物的概念

事务指逻辑上的一组操作,组成这组操作的各个单元要么全部成功、要么全部失败.在不同的环境中都可以有事务,对应在数据库中就是数据库事务.

为什么要使用事务

以如下例子说明:

准备测试表

-- 准备测试表
drop table if exists account;
create table account(
    id int primary key auto_increment,
    name varchar(20) comment '账户名称',
    money decimal(11,2) comment '金额'
);

-- 插入测试数据
insert into account(name, money) values
('张三', 5000),
('李四', 1000);

比如说现在张三要给李四转账2000元,那么张三的余额减少2000元,李四的余额增加2000元

-- 张三账户余额减少2000
update account set money = money-2000 where name = '张三';
-- 李四账户余额增加2000
update account set money = money+2000 where name = '李四';

但是如果在执行第一条SQL语句时,出现网络错误或者是数据库挂掉了,此时张三的余额减少了2000元,但是李四的余额却没有增加,此时就需要用到事务来控制,以此来保证以上两个语句要么全部执行成功,要么全部执行失败. 

事务的特性(ACID)

· 原子性:事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么全部不起作用.

· 一致性:执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的.

· 隔离性:并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的.

· 持久性:一个事务被提交之后,它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响.

事务的使用

①开启事务

-- 开启事务
start transaction;

②执行多条语句

③回滚或提交事务

-- 回滚或提交事务
rollback/commit;

rollback即全部失败,commit即全部成功.

例如:

· 回滚事务

sql语句执行完之后回滚事务,即执行的sql语句全部失败,此时张三和李四的余额都未发生改变

-- 事务的使用
start transaction;
-- 张三账户余额减少2000
update account set money = money-2000 where name = '张三';

-- 李四账户余额增加2000
update account set money = money+2000 where name = '李四';

-- 回滚事务
rollback;

· 提交事务

 sql语句执行完之后提交事务,即执行的sql语句全部成功,此时张三和李四的余额都依照sql语句的更改成功发生改变

-- 事务的使用
start transaction;
-- 张三账户余额减少2000
update account set money = money-2000 where name = '张三';

-- 李四账户余额增加2000
update account set money = money+2000 where name = '李四';

-- 回滚事务
commit;

可能产生的问题

丢失更新

比如用户1和用户2同时开启了客户端,事务1修改的数据在事务2修改以后就被覆盖掉了(相当于丢失). 

通俗的来说就是:比如A同学和B同学同时一起参加考试,B同学承诺A同学写完试卷后给他传递答案,B同学的填空题第一次写的是10,A同学抄完答案后也写了10,但是B同学经过检查后修改了答案,变成了20,但是A同学却没有修改,最终A同学填空题0分,B同学填空题100分,这就是丢失更新

脏读

第一个事务修改了数据但没有提交,第二个事务就进行读取,在第一个事务回滚后,第二个事务读取的就是脏数据.

就比如A同学和B同学同时参加考试,两个人坐在一起,A同学的填空题最初写的是10,这本应是正确答案,但A同学在检查时计算失误,将答案改成了20,此时B同学看到A同学填空题是20,就也在自己试卷上写了20;A同学又检查了一遍发现正确答案就是10,随即又改了回去,但B同学却没有改,在成绩公布后B同学0分,A同学100分,这就是脏读.

不可重复读

一个事务两次读取数据,中间有另一个事务修改了数据,第一个事务两次读取的数据就不一致

例如:A同学和B同学同时参加,A同学的填空题答案最初是10,B同学第一次偷看A同学答案看到了是10,但A同学检查完试卷后,将答案修改成了20,此时B同学又偷看了A同学的试卷,发现答案改成了20,此时B同学在10和20之间纠结,不知道究竟哪一次看到的答案是正确答案,这就是不可重复读

幻读

一个事务两次读取,中间有另一个事务执行了插入操作,造成第一个事务看到了不同的结果.

如何解决使用事务时产生的问题?

使用隔离级别来解决丢失更新脏读不可重复读幻读这四个使用事务时可能会遇到的问题,隔离级别有四个:未提交读提交读可重复读可串行化.

安全性大小为:未提交读<提交读<可重复读<可串行化;

性能比较为: 未提交读>提交读>可重复读>可串行化;

越安全,其性能越差

· 未提交读(READ UNCOMMITTED)

事务中的修改,即使没有提交,对其他事务也是可见的.

一般不会被使用,因为其安全性太差了.

· 提交读(READ COMMITTED)

一个事务只能读取已经提交的事务所做的修改。也就是说,一个事务在所做的修改提交之前对其他事务是不可见的

一般使用的比较广泛

· 可重复读(REPEATABLE READ)

保证在同一事务中多次读取同一数据的结果是一样的.

可重复读是mysql默认的隔离级别.

· 可串行化(SERIALIZABLE) 

强制事务串行执行,这样多个事务互不干扰,不会出现并发一致性问题

几乎不会被互联网公司使用,因为其性能太差

隔离级别脏读不可重复读幻读
未提交读×××
提交读××
可重复读×
可串行化

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Li_yizYa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值