MySQL>>事务

事务

情景带入: A给B转账,B这边没收到,而A这边已经扣除了.不符合实际.转账的时候显然是对于数据进行操作,会执行sql语句.
事务就是用来解决上述问题的.
事务的本质就是把多个sql语句打包成一个整体,要么全执行成功,要么全都不执行.
换言之,就是把你的操作统一化,要么所有操作都成功,要么就都不成功,如果执行中有某一项操作失败,其之前所有的操作都回滚到未执行这一系列操作之前的状态。
事务的四大特性:

  1. 原子性
  2. 一致性
  3. 持久性
  4. 隔离性

如何开启事务?

  • 开启事务
start transaction;
  • 需要执行事务的sql语句
  • 结束事务
commit;

原子性

上述将数据打包成一个整体,操作统一化.这就是原子性. 也就是说将转账过程中的一系列操作看做一个整体.

一致性

事务执行前后,数据是按要求改变的.符合逻辑的. 即A给B转账,A这边应扣除m,B这边应增加m.是一一对应的.

持久性

一个事务一旦提交,它对数据库中数据的改变就应该是永久性的. 事务修改的内容是写到硬盘上的,持久存在的.重启也不丢失.

隔离性

在实际生活中,一个服务器是面向好多个客户端的,当多个客户端进行请求的时候,服务器就要同时处理这些客户端请求.
将服务器同时处理多个客户端请求称为并发.
对于隔离性,就是为了解决并发执行事务所引起的问题.

并发执行事务引起的问题:

  • 若修改同一个表/同一个数据,就可能会出现问题.

对于问题,分为以下几种:

  1. 脏读
  2. 不可重复读
  3. 幻读

脏读

事务A正在对数据进行修改的过程中,事务B对该数据进行读取. 此时B的读操作就是脏读问题,读到的数据称为"脏数据".在如下场景里面:
在这里插入图片描述
上述针对同一个账户,当事务A在存款的过程中,事务B进行取款.A先提交事务使得账户存款修改为2000,但B后提交事务对数据进行了再次修改,使得最终账户余额记录为0.

解决方法:

  • MySQL引入 “写操作加锁” 这样的机制 . 即事务A写数据的时候,事务B不能进行读取操作

特点:

  • 意味着写操作和读操作不能同时进行, 即不能并发执行
  • 降低并发程度(降低效率),提高隔离性(提高了数据的准确性)

不可重复读(前后多次读取,数据内容不一致)

情景带入: A同学发布了一篇文章(版本1),并把文章分享给B同学.在B同学读的过程中,A同学对文章进行修改,随后发布版本2.
于是在B同学读的过程中,就会发现文章和之前有点不一样了.即两次读文章发生了不一样的内容.这就叫做不可重复读.

不可重复读:

  • 事务A已经提交了数据,此时事务B开始读取数据.在读取过程中,事务A又一次提交了数据.
  • 这时,意味着事务B多次读取数据,读出来的结果不一样. 就叫做不可重复读.
  • 换言之,不可重复读: 第二次读取的结果不能复现第一次的结果(两次结果不一样)

解决方法:

  • 在事务B读取的过程中也进行加锁.(读加锁) 读完就解锁

特点:

  • 降低并发程度(降低效率)
  • 提高隔离性(提高数据准确性)

幻读(前后多次读取,数据总量不一致)

情景带入: 在读加锁,写加锁的前提下,A同学又发布了一篇文章,在B读取的过程中,发现多了一篇文章.这就是幻读.
在读加锁和写加锁的前提下,一个事务两次读取同一个数据,发现读取的数据值是一样的,但是结果集不一样. 称为幻读
即,A同学第一篇文章内容和之前是一样的,但多了一篇文章,文章总量与读之前是不一样的.
解决方法:

  • 数据库使用"串行化"这样的方式来解决幻读.彻底放弃并发执行,一个接一个的串行处理事务

特点:

  • 并发程度最低(效率最低)
  • 隔离性高(数据最准确)

总结:

  • 针对脏读: 采用写加锁.
  • 针对不可重复读: 采用读加锁
  • 针对幻读: 采用彻底串行化.

针对上述问题,数据库提供了四种隔离级别,分别对应上述情况.

数据库四个隔离级别

在这里插入图片描述
对应解释(MySQL默认采用第三种隔离级别):
在这里插入图片描述

至于选用哪种隔离级别,根据业务来定.它们没有好坏之分.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值