zoukankan      html  css  js  c++  java
  • 数据库系统原理

    一、事务

      什么是事务呢?事务是具有ACID特性的一组操作,可以通过commit进行提交事务,也可以通过rollback对事务进行回滚。

      

      ACID
      1. 原子性(Atomicity)
        整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
      2. 一致性(Consistency)   
        一个事务可以封装状态改变(除非它是一个只读的)。事务必须始终保持系统处于一致的状态,不管在任何给定的时间并发事务有多少。
      也就是说:如果事务是并发多个,系统也必须如同串行事务一样操作。其主要特征是保护性和不变性(Preserving an Invariant),以转账案例为例,假设有五个账户,每个账户余额是100元,那么五个账 户总额是500元,如果在这个5个账户之间同时发生多个转账,无论并发多少个,比如在A与B账户之间转账5元,在C与D账户之间转账10元,在B与E之间转账15元,五个账户总额也应该还是500元,这就是保护性和不变性。
      3. 隔离性(Isolation)
        隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。
      4. 持久性(Durability)
        一旦事务提交,则其所做的修改将会永远保存到数据库中。即使系统发生崩溃,事务执行的结果也不能丢失。
      使用重做日志来保证持久性。
     
      
      事务的 ACID 特性概念简单,但不是很好理解,主要是因为这几个特性不是一种平级关系:
    • 只有满足一致性,事务的执行结果才是正确的。
    • 在无并发的情况下,事务串行执行,隔离性一定能够满足。此时只要能满足原子性,就一定能满足一致性。
    • 在并发的情况下,多个事务并行执行,事务不仅要满足原子性,还需要满足隔离性,才能满足一致性。
    • 事务满足持久化是为了能应对数据库崩溃的情况。
      AUTOCOMMIT
      MySQL 默认采用自动提交模式。也就是说,如果不显式使用 START TRANSACTION 语句来开始一个事务,那么每个
    查询都会被当做一个事务自动提交。
     

    二、并发一致性问题

      在并发环境下,由于事务的隔离性很难保证,所以会产生并发一致性问题。

      并发一致性问题主要有以下四种

    1. 丢失修改
    2. 数据脏读
    3. 幻影读
    4. 不可重复读

      我们假设目前有两个事务,Transaction1和Transaction2,简称T1、T2 它们目前处于并发执行状态,由于隔离性不能保证的情况下,出现了以上四种情况。

    首先是丢失修改,T1 和 T2 两个事务都对一个数据进行修改,T1 先修改,T2 随后修改,T2 的修改覆盖了 T1 的修改。其次是数据脏读,T1对数据进行修改的同时

    T2对数据进行了读取,但是T1最后进行了回滚操作,但是T2读取了T1修改后的数据造成了脏读数据。然后就是幻影读,T1在对一个数据范围进行读取的时候,T2

    对范围新增了数据,导致T1的读取结果与预期不一致。最后是不可重复读,T1事务对数据有两次读取操作,但在T1事务执行期间,T2事务对数据做了修改,导致T1

    事务的第二次读取事务的结果和第一次不一致。 

      产生并发不一致性问题主要原因是破坏了事务的隔离性,解决方法是通过并发控制来保证隔离性。并发控制可以通过
    封锁来实现,但是封锁操作需要用户自己控制,相当复杂。数据库管理系统提供了事务的隔离级别,让用户以一种更
    轻松的方式处理并发一致性问题。

    三、封锁 

      封锁粒度
     
      MySQL 中提供了两种封锁粒度:行级锁以及表级锁。
    应该尽量只锁定需要修改的那部分数据,而不是所有的资源。锁定的数据量越少,发生锁争用的可能就越小,系统的
    并发程度就越高。
    但是加锁需要消耗资源,锁的各种操作(包括获取锁、释放锁、以及检查锁状态)都会增加系统开销。因此封锁粒度
    越小,系统开销就越大。
    在选择封锁粒度时,需要在锁开销和并发程度之间做一个权衡。

      封锁类型 

    1. 读写锁
    • 排它锁   简写为 X 锁,又称写锁
    • 共享锁   简写为 S 锁,又称读锁。
      2. 意向锁
      使用意向锁(Intention Locks)可以更容易地支持多粒度封锁。
    在存在行级锁和表级锁的情况下,事务 T 想要对表 A 加 X 锁,就需要先检测是否有其它事务对表 A 或者表 A 中的任
    意一行加了锁,那么就需要对表 A 的每一行都检测一次,这是非常耗时的。
    意向锁在原来的 X/S 锁之上引入了 IX/IS,IX/IS 都是表锁,用来表示一个事务想要在表中的某个数据行上加 X 锁或 S
    锁。有以下两个规定:
      一个事务在获得某个数据行对象的 S 锁之前,必须先获得表的 IS 锁或者更强的锁;
      一个事务在获得某个数据行对象的 X 锁之前,必须先获得表的 IX 锁。
      通过引入意向锁,事务 T 想要对表 A 加 X 锁,只需要先检测是否有其它事务对表 A 加了 X/IX/S/IS 锁,如果加了就表
    示有其它事务正在使用这个表或者表中某一行的锁,因此事务 T 加 X 锁失败。
      总结:
      首先我们知道了事务的概念:是一组具有ACID特性的操作,由于在并发环境下,事务会出现同时处理操作的现象,导致了事务的隔离性得不到保证,隔离性得不到保证就会使的
    事务的一致性出错,从而导致并发一致性的一系列问题:脏读、幻读、不可重复读、丢失修改等。而解决的办法就是进行封锁,封锁有封锁粒度和封锁类型两个概念,封锁粒度有
    行级锁和表级锁,封锁类型有 读写锁、意向锁,读写锁又包括了排它锁(写锁)、共享锁(读锁),最后就是对数据库表进行加锁操作是兼容性的问题。
     
     
     
     
  • 相关阅读:
    ZooKeeper详解
    数据结构与算法2——数组
    jquery复习笔记
    关于水平居中
    回顾这些日子
    阻止事件冒泡
    css导航栏
    js正则
    js事件绑定
    操作iframe
  • 原文地址:https://www.cnblogs.com/ring2/p/11079137.html
Copyright © 2011-2022 走看看