avatar

目录
mysql 相关问题(一) 事务与锁

事务的基本特性和隔离级别

事务基本特性 ACID 分别是:

  • 原子性:指一个事务中的操作要么全部成功,要么全部失败。
  • 一致性:指数据库总是从一个一致性的状态转换到另外一个一致性的状态。
  • 隔离性:指一个事务的修改在最终提交前,对其他事务是不可见的。
  • 持久性:指一旦一个事务提交,所做的修改就会永久保存在数据库中。

事务的隔离级别有 4 种,分别是:

  • 读未提交:可能会读到其他事物未提交的数据,叫做脏读。
  • 读已提交:可能会造成两次读取结果不一致,叫做不可重复读。
  • 可重复读:是 mysql 的默认级别,就是每次读取结果都一样,但是可能产生幻读。
  • serializable 串行化:一般是不会使用的,他会给每一行读取的数据加锁,会导致大量超时和锁竞争问题。

不可重复读和幻读的区别

不可重复读重点在于 update 和 delete,幻读的重点在于 insert。

在可重复读中,该 sql 第一次读取到数据后,就将这些数据加锁,其他事务就无法修改这些数据了,就可以实现可重复读了。但是这种方法却无法锁住 insert 的数据,
所以当事务 A 先读取了数据,或者修改了全部数据,事务 B 还是可以 insert 数据提交,这时事务 A 就会发现莫名其妙多了一条之前没有的数据,这就是幻读。不能通过行锁来避免。
需要 Serializable 隔离级别,读用读锁,写用写锁,读锁和写锁互斥,这么做可以有效的避免幻读、不可重复读、脏读等问题,但会极大地降低数据库的并发能力。

那 ACID 靠什么保证的呢?

  • A 原子性 由 undo log 日志保证,它记录了需要回滚的日志信息,事务回滚时撤销已经执行成功的 sql
  • C 一致性一般由代码层面来保证
  • I 隔离性由 MVCC 来保证
  • D 持久性,由内存 + redo log 来保证,mysql 修改数据同时在内存和 redo log 记录这次操作,事务提交的时候通过 redo log 刷盘,宕机的时候可以从 redo log 恢复。
文章作者: Viola Tangxl
文章链接: https://violatangxl.github.io/2021/03/07/mysql-01/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 椰子是只猫
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论