聊一聊MySQL的事务

我们先来明确一下什么是事务:我们在业务中往往不止有一条sql,多条sql要么全部执行成功,要么全部执行失败,不能一条成功一条失败,这就叫做事务。全部执行成功就会commit,将数据写入数据库,有一条失败就会rollback。

其次我们要确定一下,以下所有内容都是基于InnoDB引擎的,因为MyISAM不支持事务

事务的ACID


事务有着四大特性:

A:原子性,事务是一个不可分割的整体,要么全执行,要么全不执行,不允许事务部分完成。

C:一致性,事务执行前后数据库状态不变,一致性必须由用户负责,并发控制机制实现。比如数据层和缓存层的数据一致性问题。

I:隔离性,当两个或者多个事务并发执行时,为了保证数据的安全性,将一个事物内部的操作与其它事务的操作隔离起来,不被其它正在执行的事务所看到,使得并发执行的各个事务之间不能互相影响。

D:一致性,事务完成(commit)以后,DBMS保证它对数据库中的数据的修改是永久性的,即使数据库因为故障出错,也应该能够恢复数据。

其中ACD三特性是由事务日志(undo log,redo log)保证的,I(隔离性)是由MVCC+锁保证的。

一个业务中可能会有多个事务,如果这些事务全部是串行执行的话,就会使效率变得低下。而支持并发执行就需要保证事务的安全性和一致性,所以要保证事务的隔离性。对了,还要注意并发效率问题

事务并发执行导致的问题


事务是支持并发执行的,而并发执行就会导致一些问题:

  1. 脏读:读取到另一个事务未commit的数据。

  1. 不可重复读:一个事务的操作导致另一个两次获取到的数据不同。

  1. 幻读:一个事务的操作导致另一个事务两次查询到的数据量不同。

事务的隔离级别


为了解决上述问题,MySQL提出了四中隔离级别:

  1. 读未提交:没有任何并发控制

  1. 读已提交:解决了脏读问题。使用MVCC实现

  1. 可重复读:解决了不可重复读问题,解决了部分幻读问题。使用MVCC+锁实现

  1. 串行化度:解决了上述三种问题,但是并发效率会变差。使用锁实现

MySQL默认的隔离级别是可重复读,Oracle默认的隔离级别使读已提交。

串行化读可以解决事务并发导致的所有问题,但这也会是事务并发执行的效率变得差。因为在串行化读隔离级别下,读写数据都会锁住整张表。所以我们并不需要去追求串行化读,因为在不同的业务场景下事务的并发问题并不算是问题

比如我们在小破站搜索视频时,第一次根据标签搜索到的视频只有两个,过了一秒闪退之后重新搜索,发现变成了三条或者更多,但这对于我们业务场景来说并不算问题。所以无需去追逐更高的隔离级别,那样会使我们的业务执行效率变差。而是选择和自己业务合适的隔离级别

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值