mysql数据库的隔离级别

系列文章

  • mysql 性能优化 | 第一篇 mysql B+Tree
  • mysql 性能优化 | 第二篇 MySql Myisam和innodb对比 索引优化建议
  • mysql 性能优化 | 第三篇 mysql存储引擎
  • mysql 性能优化 | 第四篇 mysql数据库的隔离级别
  • mysql 性能优化 | 第五篇 mysql 表锁 行锁
  • mysql 性能优化 | 第六篇 mysql MVCC Undo Redo
  • mysql 性能优化 | 第七篇 mysql 执行路径 执行计划 慢查询
  • mysql 性能优化 | 第八篇 mysql 配置优化

1.事务的特性

ACID

1.1原子性

事务中的操作,要么全部成功,要么全部失败;对于一个事务来说,不可能只执行其中的一部分操作

1.2一致性

数据库总是从一个一致性的状态转换到另一个一致性的状态

原子性一致性的侧重点不同:原子性关注状态,要么全部成功,要么全部失败,不存在部分成功的状态。而一致性关注数据的可见性,中间状态的数据对外部不可见,只有最初状态和最终状态的数据对外可见

1.3隔离性

并发过程中,事务在最终提交之前是相互隔离的,不能相互干扰

1.4持续性

一旦事务提交,则其所做的修改不会永久保存到数据库

2事务并发产生的问题

2.1脏读

  1. 事务A第一次读取到price=100
  2. 同时事务B更新update price=120,但是此时的事务B还未commit
  3. 事务A读取的price=120
  4. 事务B->rollback操作
  5. 事务A读取到的是脏数据
    mysql数据库的隔离级别_第1张图片

2.2不可重复读

  1. 事务A第一次读取到price=100
  2. 同时事务B更新update price=120,并commit
  3. 事务A读取的price=120
  4. 事务A多次读取的结果不一致
    mysql数据库的隔离级别_第2张图片

2.3幻读

幻读和不可重复读的区别在于,幻读主要表现在数据的删除插入,而不可重复读表现在数据的更新

  1. 事务A第一次读取到price=100
  2. 同时事务B更新delete price=100 这条记录,并commit
  3. 事务A读取的price=100
  4. price这条记录已经不存在,但是事务A还是可以读取到
    mysql数据库的隔离级别_第3张图片

3数据库提供的解决方法

mysql提供了4种隔离级别

3.1read uncommitted 未提交读

2.1中脏读的场景,事务A可以读取到事务B update->price = 120 还未提交的值,但是如果事务B没有commit而是rollback就会产生脏读问题

这种隔离级别最低,但是并发性能最好,事务A不需要阻塞等待事务B去完成提交

3.2read committed 已提交读

可以解决上面脏读的问题

读取已经commit的内容,事务A必须等事务Bcommit之后再去读取price更新之后的值

但是它存在不可重复读的问题,同一事务范围内多次读取的数据不一致

3.3repeatable read 可重复读

mysql默认的隔离级别

就是解决不可重复读的问题,保证同一事务读取的值是一致的

3.4serializable 可串行化

多个事务并发,串行排队执行,事务A必须等待事务B全部执行完,才开始执行

这种隔离级别最高,但是并发性能最差,相当于java中synchronized重量级锁

4.总结

数据隔离的级别越高,并发性能越差,反之亦然

四种隔离级别存在的问题,√表示依然存在问题,×表示已经不存在问题

注:InnoDB中虽然是repeatable read隔离级别,但是解决了幻读问题,通过Next-key Locks+MVCC的方式

隔离级别 脏读 不可重复读 幻读
read uncommitted(未提交读)
read committed(已提交读) ×
repeatable read(可重复读) × × √ (InnoDB为×)
serializable(可串行化) × × ×

你可能感兴趣的:(数据库,mysql,性能优化)