MySQL 整体架构与 SQL 执行原理( 四 )


MySQL使用基于成本的优化器 , 它尝试预测一个查询使用某种执行计划时的成本 , 并选择其中成本最小的一个 。在MySQL可以通过查询当前会话的last_query_cost的值来得到其计算当前查询的成本 。
数据库事务的概念及其实现原理
数据库事务(Database Transaction)概述
什么是事务?

  • 转账的例子
  • 1.转账操作的第一步执行成功,A账户上的钱减少了100元,但是第二步执行失败或者未执行便发生系统崩溃,导致B账户并没有相应增加100元 。
  • 2.转账操作刚完成就发生系统崩溃,系统重启恢复时丢失了崩溃前的转账记录 。
  • 3.同时又另一个用户转账给B账户,由于同时对B账户进行操作,导致B账户金额出现异常 。
  • 1.将A账户的金额减少100元
  • 2.将B账户的金额增加100元 。
  • 从A账户转账100元到B账号 。站在用户角度而言,这是一个逻辑上的单一操作,然而在数据库系统中,至少会分成两个步骤来完成:
  • 在这个过程中可能会出现以下问题:
  • 为了便于解决这些问题,需要引入数据库事务的概念 。
  • 定义
  • 数据库管理系统执行过程中的一个逻辑单位 , 由一个有限的数据库操作序列构成 。
  • 必须满足ACID属性
  • 例子
  • 一个典型的数据库事务如下所示
BEGIN TRANSACTION //事务开始 SQL1 SQL2 COMMIT/ROLLBACK //事务提交或回滚
为什么要有事务?
  • 为数据库操作序列提供了一个从失败中恢复到正常状态的方法 , 同时提供了数据库即使在异常状态下仍能保持一致性的方法 。
  • 当多个应用程序在并发访问数据库时 , 可以在这些应用程序之间提供一个隔离方法 , 以防止彼此的操作互相干扰 。
ACID 特性
  • 原子性(Atomicity):事务作为一个整体被执行 , 包含在其中的对数据库的操作要么全部被执行 , 要么都不执行 。
  • 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态 , 一致状态的含义是数据库中的数据应满足完整性约束 。
  • 隔离性(Isolation):多个事务并发执行时 , 一个事务的执行不应影响其他事务的执行 。
  • 持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中 。
隔离级别
  • 四个级别
  • Read Uncommitted 读未提交:就是一个事务可以读取另一个未提交事务的数据 。
  • Read Committed 读提交:就是一个事务要等另一个事务提交后才能读取数据 。若有事务对数据进行更新(UPDATE)操作时 , 读操作事务要等待这个更新操作事务提交后才能读取数据 , 可以解决脏读问题 。
  • Repeatable Read 重复读:就是在开始读取数据(事务开启)时 , 不再允许修改操作 。重复读可以解决不可重复读问题 。写到这里 , 应该明白的一点就是 , 不可重复读对应的是修改 , 即UPDATE操作 。但是可能还会有幻读问题 。因为幻读问题对应的是插入INSERT操作 , 而不是UPDATE操作 。
  • Serializable 顺序读:是最高的事务隔离级别 , 在该级别下 , 事务串行化顺序执行 , 可以避免脏读、不可重复读与幻读 。但是这种事务隔离级别效率低下 , 比较耗数据库性能 , 一般不使用 。
  • mysql 对应的InnoDB默认隔离级别是 重复读
  • 所有事务隔离级别都不允许出现脏写,而串行化可以避免所有可能出现的并发异常,但是会极大的降低系统的并发处理能力 。
  • 共享锁与排它锁
  • 排它锁
  • 共享锁
  • 隔离怎么实现?
  • 共享锁(S锁) :(插入/修改/删除)资源获取S锁之后 , 能加S锁 , 不能加X锁
  • 排它锁(X锁) :资源加上X锁之后 , 不能加S锁 , 也不能加X锁
  • InnoDB存在两种锁
数据库事务实现原理剖析
事务的实现原理