mysql 事务

一、事务定义

  事务:一个最小的不可再分的工作单元;通常一个事务对应一个完整的业务(例如银行账户转账业务,该业务就是一个最小的工作单元);一个完整的业务需要批量的DML(insert、update、delete)语句共同联合完成,事务只和DML语句有关,或者说DML语句才有事务。这个和业务逻辑有关,业务逻辑不同,DML语句的个数不同

二、事务四大特征(ACID)

  • A(atomicity)原子性:一个事务必须被视为一个不可分割的最小单位,要不全部提交成功,要么全部失败回滚。
  • C(consistency)一致性:数据库总是从一个一致性的状态转换到另外一个一致性状态,不会部分数据状态改变了部分状态没有改变。
  • I(isolation)隔离性:通常来说,一个事务所做的修改在最终提交之前,对其他事务是不可见的。这个和数据库的隔离级别有关,所以只能通常来说。
  • D(durability)持久性:一旦事务提交,则其所做的修改会被永久保存到数据库中。


三、实现方式

​        原子性:原子性是通过undo log日志进行实现的。当事务需要回滚时,InnoDB引擎就会调用undo log进行SQL语句的撤销,实现数据的回滚。undo log是InnoDB引擎提供的日志。当事务对数据库进行修改,InnoDB不仅会记录redo log,还会生成对应的undo log。如果事务执行失败或调用了rollback,导致事务需要回滚,就可以利用undo log中的信息将数据回滚到修改之前的样子。但是undo log于redo log不同,它属于逻辑日志。它对SQL语句执行相关的信息进行记录。当发生回滚时,InnoDB引擎会根据undo log日志中的巨鹿做与之前相反的工作。比如对于每个数据的插入操作(insert),回滚时会执行数据删除操(delete);对于每个数据删除操作(delete),回滚时会执行数据插入操作(insert);对于每个数据更新操作(update),回滚时会执行一个相反的数据更新操作(update),把数据改回去。undo log有两个作用,一是提供回滚,二是实现MVCC功能。
​        持久性:事务的持久性是通过InnoDB存储引擎中的redo log日志来实现的。重做日志(redo log)是InnoDB引擎层的日志,用来记录事务操作引起数据的变化,记录的是数据页的物理修改。InnoDB引擎对数据的更新,是先将更新记录写入redo log日志,然后会在系统空闲的时候或者是按照设定的更新策略再将日志中的内容更新到磁盘之中。这就是所谓的预写式技术(Write Ahead logging)。这种技术可以大大减少IO操作的频率,提升数据刷新的效率。redo log有一些细节需要我们注意,redo log日志的大小是固定的,为了能够持续不断的对更新记录进行写入,在redo log日志中设置了两个标志位置,checkpoint和write_pos,分别表示记录擦除的位置和记录写入的位置。这种结构很像一个循环队列:

​        隔离性:事务之间的隔离,是通过锁机制实现的。当一个事务需要对数据库中的某行数据进行修改时,需要先给数据加锁。加了锁的数据,其它事务是不运行操作的,只能等待当前事务提交或回滚将锁释放。锁机制并不是一个陌生的概念,在许多场景中都会利用到不同实现的锁对数据进行保护和同步。而在MySQL中,根据不同的划分标准,还可将锁分为不同的种类:
      a 粒度划分:行锁、表锁、页锁

      MySQL中不同的存储引擎能够支持的锁也是不一样的。MyISAM只支持表锁,而InnoDB同时支持表锁和行锁,且出于性能考虑,绝大多数情况下使用的都是行锁。InnoDB 行锁是通过给索引项加锁实现的,如果没有索引,InnoDB会通过隐藏的聚簇索引来对记录加锁。也就是说,如果不通过索引条件检索数据,那么InnoDB将对表中所有数据加锁,实际效果跟表锁一样。因为没有了索引,找到某一条记录就得扫描全表,要扫描全表,就得锁定表。


      b 使用方式划分:共享锁、排他锁

      共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。排他锁又称为写锁,简称X锁,顾名思义,排他锁就是不能与其他所并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁。获取排他锁的事务是可以对数据就行读取和修改。

      c 思想划分:悲观锁、乐观锁
      悲观锁(Pessimistic Concurrency Control),正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。乐观锁通常使用版本标识方法来实现,比如MVCC。

​        一致性: 一致性是指事务执行结束后,数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态。一致性是事务追求的最终目标,原子性、持久性和隔离性,实际上都是为了保证数据库状态的一致性而存在的。



    

 

posted on 2021-08-07 11:13  胡子就不刮  阅读(158)  评论(0编辑  收藏  举报

导航