数据库学习思路整理之事务

事务学习思路整理

事务基本理论

概念:

   事务就是一组原子性的SQL查询,或者说一个独立的工作单元。事务内的语句,要么全部执行,要么全部失败。
   例如:在银行的一个账号上进行转账操作,转账过程包括三个步骤,检查余额,该账户减去存款,对应帐号增加存款。这个过程中可能存在的问题:
   脏读(Dirty Read):一个事务读取了另一个事务未提交的数据。例如当事务A和事务B并发执行时,当事务A更新后,事务B查询读取到A尚未提交的数据,此时事务A回滚,则事务B读到的数据就是无效的脏数据。(事务B读取了事务A尚未提交的数据)
   不可重复读(NonRepeatable Read): 一个事务的操作导致另一个事务前后两次读取到不同的数据。例如当事务A和事务B并发执行时,当事务B查询读取数据后,事务A更新操作更改事务B查询到的数据,此时事务B再次去读该数据,发现前后两次读的数据不一样。(事务B读取了事务A已提交的数据)
   虚读(Phantom Read)/幻读:一个事务的操作导致另一个事务前后两次查询的结果数据量不同。例如当事务A和事务B并发执行时,当事务B查询读取数据后,事务A新增或者删除了一条满足事务B查询条件的记录,此时事务B再去查询,发现查询到前一次不存在的记录,或者前一次查询的一些记录不见了。(事务B读取了事务A新增加的数据或者读不到事务A删除的数据。

所以,这三个步骤的操作必须打包在一个事务当中,任何一个步骤失败,都必须回滚所有操作。
特性:
原子性 :undo log日志
持久性:redo log日志
隔离性:锁机制+MVCC机制

  1. 锁机制:根据不同的维度有这几种分类
    record locks(记录锁):在索引的记录上加锁
    gap locks(间隙锁):在索引记录之间加锁,或者在第一个索引记录之前加锁,或者在最后一个索引记录。
    next-key locks:在索引记录上加锁,并且在索引记录之前的间隙加锁。它相当于是record locks和gap locks的一个结合。
    共享读锁和排他写锁:
    共享锁:允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁。
    排他锁:允许获得排他锁的事务更新数据,阻止其他事务取得相同数据集的。
    行锁和表锁:
    表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
    行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最 低,并发度也最高
    MVCC机制(多版本并发控制):所谓的mvcc机制就是尽量的不去使用这些锁,一旦这些锁加上之后事务与事务之间就变成了完全的串行执行,在隔离级别中串行化其实就是这样做的。这里又要涉及到我们之前所学的乐观锁和悲观锁。
    InnoDB的一致性的非锁定读就是通过在MVCC实现的,Mysql的大多数事务型存储引擎实现的都不是简单的行级锁。基于提升并发性能的考虑,它们一般都同时实现了多版本并发控制(MVCC)。MVCC的实现,是通过保存数据在某一个时间点的快照来实现的,,每一个事务只操作自己版本下的数据。因此每一个事务无论执行多长时间看到的数据,都是一样的。所以MVCC实现可重复读。
  2. 隔离性一共分了4种隔离级别。
    分别是:未提交读,已提交读,可重复读,和序列化
    未提交读(Read uncommitted):这种级别,数据库一般都不会用,而且任何操作都不会加锁,这里就不讨论了。
    已提交读(Read committed):在RC级别中,数据的读取都是不加锁的,但是数据的写入、修改和删除是需要加锁的(Record Locks)。那么已提交读时如何解决脏读问题的?这个就利用了mvcc机制,
    可重复读(Repeatable read):数据的读取都是不加锁的,但是数据的写入、修改和删除是需要加锁(Record Locks)的+Mvcc机制
    序列化(Serializable):这个级别很简单,读加共享锁,写加排他锁,读写互斥。使用的悲观锁的理论,(加的锁就是Next-Key Locks)实现简单,数据更加安全,但是并发能力非常差。如果你的业务并发的特别少或者没有并发,同时又要求数据及时可靠的话,可以使用这种模式。由于InnoDB引擎加的是行锁,并且是加在索引记录上,所以为了不产生幻读在还会加间隙锁。
    结果:
    隔离级别
    隔离级别| 脏读 不可重复读 幻读
    未提交读| 可以 可以 可以
    已提交读| 不可以 可以 可以
    可重复读| 不可以 不可以 可以
    串行化 | 不可以 不可以 不可以

一致性:原子性+持久性+隔离性,这三者结合去实现。

你可能感兴趣的:(mysql)