常见的锁类型有以下几种

1.表级锁(Table Lock)test

通俗解释:好比把整个餐厅锁起来。一个人要做大扫除时,锁上餐厅门,其他人都进不去。这样不会有任何冲突,但其他人只能等大扫除完成后再进入餐厅。

特点:

开销小,锁得快。

不会有死锁,因为只有一个人能进餐厅。

并发性最低,因为一次只能一个人进

2.行级锁(Row Lock):

通俗解释:好比锁住餐厅里的一张桌子。每个人可以锁住自己那张桌子,做自己的事,互不干扰。虽然可能会有冲突,比如两个人同时想用同一张桌子,但总体上大家可以同时工作。

特点:

开销大,锁得慢。

可能会出现死锁,比如两个人互相等对方释放桌子。

并发性最高,因为很多人可以同时在不同的桌子上工作。

3.页面锁(Page Lock):

通俗解释:好比把餐厅里的一个区域锁起来。一个人锁住一个区域,这个区域里的人不能同时工作,但其他区域的人可以继续工作。

特点:

开销和速度介于表锁和行锁之间。

也可能会出现死锁。

并发性一般。

  1. Read Uncommitted(读未提交)

    • 案例:事务A读取账户余额,事务B正在将账户余额从1000元改为2000元,但还没有提交。

    • 过程

      1. 事务B将余额改为2000元,但还未提交。
      2. 事务A读取余额,看到的是2000元(未提交的数据)。
      3. 事务B回滚(因为某种原因)。
      4. 事务A读到的2000元其实是无效的数据。
    • 问题:脏读,事务A读取到了事务B未提交的数据。

  2. Read Committed(读已提交)

    • 案例:事务A读取账户余额,事务B正在将账户余额从1000元改为2000元,并提交。

    • 过程

      1. 事务A读取余额,看到的是1000元。
      2. 事务B将余额改为2000元,并提交。
      3. 事务A再次读取余额,看到的是2000元。
    • 问题:不可重复读,事务A两次读取同一个数据,结果不同。

  3. Repeatable Read(可重复读)

    • 案例:事务A读取账户余额,事务B正在将账户余额从1000元改为2000元,并提交。

    • 过程

      1. 事务A读取余额,看到的是1000元。
      2. 事务B将余额改为2000元,并提交。
      3. 事务A再次读取余额,仍然看到的是1000元。
    • 问题:幻读,虽然避免了不可重复读,但在某些情况下,新增的数据可能会造成幻觉。例如,事务B插入了新的符合事务A查询条件的记录。

  4. Serializable(可串行化)

    • 案例:事务A读取账户余额,事务B尝试将账户余额从1000元改为2000元。

    • 过程

      1. 事务A读取余额,看到的是1000元。
      2. 事务B尝试修改余额,但会被阻塞,直到事务A结束。
      3. 事务A提交或回滚。
      4. 事务B修改余额,并提交。
    • 问题:没有并发问题,所有操作都是串行执行的,确保了最高的数据一致性,但性能可能会受到影响,因为事务B必须等待事务A完成。

总结

  • Read Uncommitted:你能看到其他人未完成的工作。
  • Read Committed:你只能看到其他人完成的工作,但每次看结果可能不一样。
  • Repeatable Read:你每次看到的结果一致,但可能会有新的数据插入影响最终结果。
  • Serializable:所有事务按顺序执行,确保完全一致,但性能最低。

通过这个案例,希望你能更清楚地理解这四种事务隔离级别的区别和应用场景。