1. 1.
    1. 1.0.1. 读写锁
    2. 1.0.2. 锁粒度
  • 2. 事务
    1. 2.0.1. 事务的基本性质(ACID)
    2. 2.0.2. 隔离级别
  • 锁、事务、隔离

    首先明确MySQL的最基础架构
    客户端/连接–>链接线程处理–>解析器–>查询缓存–>优化器–>存储引擎–>数据

    对于客户端/连接,需要明确,每一个客户端连接都会独立的拥有一个线程,所以当多个查询再同一时刻读写数据时,就容易产生冲突,为了避免冲突发生,我们需要做好并发控制,保证一个线程的运行不会对其他线程的运行产生预料外的影响。

    读写锁

    多个线程同时读取统一数据显然不会发生问题,但如果多个线程同时有读有写,就会造成两个线程对于同一个语句读取到的数据不一致的问题,因此,为了安全起见,我们要为数据加锁

    • 共享锁/读锁/乐观锁/协同锁
      被锁定的数据不可以被其他线程重复写入,但可以被其他线程读取
    • 排他锁/写锁/悲观锁/强制锁
      被锁定的数据不可以被其他线程重复写入,也不可以被其他线程读取

    锁粒度

    如果被锁定的数据过多,则会造成其他同样需要该数据的线程阻塞的情况,一般来说,在MySQL中,存在两种粒度

    • 表锁
      读取时会锁定整张表
    • 行级锁
      读取时只会锁定行
      锁的实现位于存储引擎层,因此存储引擎之上的层并不会知晓锁的情况和概念

    事务

    事务的基本性质(ACID)

    • 原子性(Atomicity)
      事务被视为不可分割的工作单元,一个事务的操作要不全部执行,要不全部不执行,事务不可以被再次切分
    • 一致性(Consistency)
      数据库永远保持一致性,如果事务没有被提交,那么其所做的修改也不会被保存到数据库中
    • 隔离性(Isolation)
      事务之间是不可见的,即正在执行(或执行完尚未提交)的事务并不会对其他事务读取到的结果造成任何影响
    • 持久性(Durability)
      一旦事务提交,则其所做的一切修改都会被永久保存并对外可见

    隔离级别

    隔离性的实现也存在级别差异,在SQL中规定了四种隔离级别,较低级别的隔离往往可以获得更高的性能
    以下为四种隔离级别:

    • 未提交读(READ UNCOMMITTED)
      事务中的修改即使没有提交也对其他事务可见

    • 提交读(READ COMMITTED)
      事务的修改只有提交后才对其他事务可见,这也是大多数数据库系统的默认隔离级别

    • 可重复读(REPEATABLE READ)
      此级别是MySQL的默认事务隔离级别,采用多版本并发控制,避免了幻读的问题

    • 可串行化(SERIALIZABLE)
      强制事务串行执行,会在读取的每一行数据都上锁,因此会导致大量的超时和锁争用问题

    • 脏读:读取到其他事务尚未提交的数据

    • 不可重复读:一个事务读取到另一个事务提交的数据,即同一个事务对于同一组数据读取到的结果不一致

    • 幻读:某个事务在读取某一范围的记录时,另一个事务又在该范围插图了新的记录,当该事务再次读取时,会发生幻行

    • 加锁读:读取必加锁
      不可重复读和幻读:不可重复读强调前后同一条数据的结果不一致,幻读强调数据多出现多行,即”幻行”