DBMS(数据库管理系统)允许多个事务并发执行:

  • 优点:
    • 增加系统吞吐量(throughput)。吞吐量是指单位时间系统完成事务的数量。当一事务需等待磁盘I/O时,CPU可去处理其它正在等待CPU的事务。这样,可减少CPU和磁盘空闲时间,增加给定时间内完成事务的数量。
    • 减少平均响应时间(average response time)。事务响应时间是指事务从提交给系统到最后完成所需要的时间。事务的执行时间有长有短,如果按事务到达的顺序依次执行,则短事务就可能会由于等待长事务导致完成时间的延长。如果允许并发执行,短事务可以较早地完成。因此,并发执行可减少事务的平均响应时间。
  • 缺点:
    • 若不对事务的并发执行加以控制,则可能破坏数据库的一致性

      三大数据不一致问题

      读脏数据

      如果事务T2读取事务T1修改但未提交的数据后,事务T1由于某种原因中止而撤销,这时事务T2就读取了不一致的数据。数据库中将这种读未提交且被撤销的数据读“脏数据”
      image.png

      丢失更新

      两个或多个事务都读取了同一数据值并修改,最后提交事务的执行结果覆盖了前面提交事务的执行结果,从而导致前面事务的更新被丢失。
      image.png

      不可重复读

      事务T1读取数据后,事务T2执行了更新操作,使T1无法再现前一次读取的结果。
      image.png

事务串行执行可保证数据库的一致性,如果能判断一个并发调度的执行结果等价于一个串行调度的结果,就称该并发调度可保证数据库的一致性。

并发控制

并发控制机制大体上可分为悲观的乐观的两种。

  • 悲观的并发控制方法认为数据库的一致性经常会受到破坏,因此在事务访问数据对象前须采取一定措施加以控制,只有得到访问许可时,才能访问数据对象,如基于封锁的并发控制方法。——事前控制
  • 乐观的并发控制方法则认为数据库的一致性通常不会遭到破坏,故事务执行时可直接访问数据对象,只在事务结束时才验证数据库的一致性是否会遭到破坏,如基于有效性验证方法。——事后验证

    基于锁的并发控制

    基本思想:当事务T需访问数据对象Q时,先申请对Q的锁。如批准获得,则事务T继续执行,且此后不允许其他任何事务修改Q,直到事务T释放Q上的锁为止。

  • 基本的锁类型:

    • 共享锁又称读锁(shared lock,记为S)︰如果事务T获得了数据对象Q的共享锁,则事务T可读Q但不能写Q。
    • 排它锁又称写锁(eXclusive lock,记为X)︰如果事务T获得了数据对象Q上的排它锁,则事务T既可读Q也可写Q。
  • 基本锁类型的封锁相容性原则:
    • 共享锁与共享锁相容
    • 排它锁与共享锁、排它锁与排它锁是不相容的。

image.png

  • 申请和释放锁操作:

    • SL(Q)或Slock(Q)——申请数据对象Q上的共享锁;
    • XL(Q)或Xlock(Q)——申请数据对象Q上的排它锁;
    • UL(Q)或Unlock(Q)——释放数据对象Q上的锁。
  • 锁的粒度

    • 锁粒度是指锁的作用范围。原则是让锁定对象更有选择性。也就是尽量只锁定部分数据,而不是所有的资源。
    • 锁粒度越,越适合做并发更新操作
    • 锁粒度越,越适合做并发查询操作
  • 锁策略是指在锁的开销和数据的安全性之间寻求平衡

    • 表级锁是MySQL中最基本的锁策略,而且是开销最小的策略
    • 行级锁可以最大程度地支持并发处理,同时也带来了最大的锁开销

      三级封锁协议

      一级封锁协议

  • 事务T在修改数据R之前必须先对其加x锁,直到事务结束才释放。事务结束包括正常结束(COMMIT)和非正常结束(ROLLBACK) 。

  • 一级封锁协议可以防止丢失更新,并保证事务T是可恢复的。
  • 在一级封锁协议中,如果仅仅是读数据而不对其进行修改,是不需要进行加锁的,所以它不能保证可重复读不读“脏”数据

image.png

二级封锁协议

  • 在一级封锁协议的基础之上增加事务T在读取数据R之前必须先对其加S锁读完后即可释放S锁
  • 二级封锁协议可以防止丢失更新,还可进一步防止读“脏”数据
  • 在二级封锁协议中,由于读完数据后即可释放S锁,所以它不能保证可重复读

image.png

三级封锁协议

  • 在一级封锁协议的基础之上增加事务T在读取数据R之前必须先对其加S锁直到事务结束才释放S锁
  • 三级封锁协议可以防止丢失更新防止读“脏”数据,还可进一步防止不可重复读

image.png

X锁 S锁 一致性保证
操作结束释放 事物结束释放 操作结束释放 事物结束释放 不丢失更新 不读“脏”数据 可重复读
一级封锁协议
二级封锁协议
三级封锁协议
  • 在默认情况下,MySQL是自动提交事务的,即每一条SELECT、INSERT、UPDATE、DELETE的SQL语句提交后会自动执行COMMIT操作。
  • 因此,要显式开启一个事务,可以使用start transaction或begin,或者将autocommit的值设置为0。

    四种隔离级别

  • 读未提交(READ-UNCOMMITTED):可读取其他事务未提交的数据,易引发脏读

  • 读已提交(READ COMMITTED):读其他事务已提交数据,防止脏读
  • 可重复读(REPEATABLE READ):MySQL默认级别。保证一个事务内多次连续读取数据的一致,但不能防止幻读,InnoDB通过多版本并发控制(MVCC)机制解决了幻读问题
  • 串行化(SERIALIZABLE):事务安全最高的隔离级别,可防止死锁,但会严重影响并发性能。

image.png