Mysql 事务特性、隔离等级等相关问题

2020-07-22  本文已影响0人  不留余白

事务的特性

  1. 原子性:所有操作一起提交,不会只执行一部分。即事务是原子性的,不可以分割。

  2. 一致性:事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。

  3. 隔离性:同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。

  4. 持久性:事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。

事务的隔离等级

  1. 读未提交:其它事务可以查询到事务A更改数据但还未提交的数据。

  2. 读已提交:只能读取到已提交的数据。

  3. 可重复读:事务A在开始时就创建一个视图,在事务中使用的数据均从这份视图中查询。

  4. 串行化: 读数据加读锁,写数据加写锁,前面的锁释放后面的事务才可以进行;完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

事务的问题

  1. 脏读:事务B读到了事务A修改的数据,后来事务A回滚,导致事务B用了错误的数据
  2. 不可重复读:事务A频繁的读取某个表的数据,事务B更改了这个表的数据,导致事务A读到的数据和之前的不一样了
  3. 幻读: 事务A将某字段的值全部都改了,事务B又将数据改为之前的数据了,导致事务A结束刷新后发现数据没有变化,就像出现了幻觉

解决方案

隔离等级 脏读 不可重复读 幻读
读未提交 未解决 未解决 未解决
读已提交 解决 未解决 未解决
可重复读 解决 解决 未解决
串行化 解决 解决 解决

其它

  1. 数据库默认隔离级别: mysql ---repeatable,oracle,sql server ---read commited

  2. mysql binlog的格式三种:statement,row,mixed

  3. 为什么mysql用的是repeatable而不是read committed:在 5.0之前只有statement一种格式,而主从复制存在了大量的不一致,故选用repeatable

  4. 为什么默认的隔离级别都会选用read commited 原因有二:repeatable存在间隙锁会使死锁的概率增大,在RR隔离级别下,条件列未命中索引会锁表!而在RC隔离级别下,只锁行

  5. 在RC级用别下,主从复制用什么binlog格式:row格式,是基于行的复制!

  6. 为什么在互联网项目中选择读已提交,而不用可重复读

    • 可重复读隔离级存在间隙锁,导致出现死锁的几率比读已提交大的多!读已提交隔离级别下,不存在间隙锁,其他事务是可以插入数据!
    • 在可重复读隔离级别下,条件列未命中索引会锁表!而在读已提交隔离级别下,只锁行
    • 在可重复读隔离级别下,半一致性读(semi-consistent)特性增加了update操作的并发性!
上一篇 下一篇

猜你喜欢

热点阅读