终于搞懂Mysql事务及实现原理

对于Mysql的事务,想必大家应该都不陌生,我们也容易联想到几个名词:ACID,要不都成功,要不都失败等等。其实我们在实际的开发过程中,一般也都会用到事务处理,如:在spring框架中相关事务的注解:@Transactional等,这里我们就展开了.

一、什么是事务(百度百科的定义)

在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transactionend transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。

     那么我们在执行一条sql语句时都会出现事务吗?其实都会创建一个事务的,而且会自动提交。在Mysql的配资中,可以查看是否自动提交等配置。其实事务的本质应该就是:保证了一个完整性,让着期间的操作变得不可以拆分(即所谓的:一起成功,一起失败,不存在中间态),若中间出现异常,那么整体执行回滚,回到初始状态

二、事务并发会引发哪些问题

  场景一 、(读取到了为提交的数据 )  --  脏读

终于搞懂Mysql事务及实现原理_第1张图片

 场景二、(读取到了已提交的数据,造成前后数据不一致问题)-- 不可重复读 

终于搞懂Mysql事务及实现原理_第2张图片

 场景三、(区间查询时,读取到了其他事务插入的数据,导致前后查询不一致问题) -- 幻读

终于搞懂Mysql事务及实现原理_第3张图片

     看做上述的场景描述不可重复度幻读感觉有点差不多,我刚开始的时候也总是将这2个场景弄混。在这里我这边做个小小的说明。一般来说:我们对数据的修改和删除造成的不一致都认为是:不可重复度,对于插入的数据造成的不一致认为是:幻读

对于读一致性,个人观点:每一次事务内操作,可以认为与其他事务互不影响的,那么这样我们在同一个事务中进行(如查询)操作的时候,理论上来说前后查询的结果应该要一致的。因为每次事务的操作在当前事务操作还未提交之前,应该只会影响该事务本身,不应该去影响别的事务的执行(只需要保证每次事务开始时,能获取到表中最新的数据即可),即各个事务之间互不影响,这就有了事务的隔离机制,事务的隔离机制有哪些呢?它又是如何处理这些问题(脏读,不可重复度,幻读)的呢?Read View机制

三、如何理解事务的四大特性(ACID)

A : Atomicity(原子性),即不可在分割,最小单位了。原子性在InnoDB中通过文件unDo.log(文件中保存了修改之前的数据,如果发生异常或需要回滚,即通过unDo.log文件恢复,实现回滚操作)来保证的。

C:Consistent(一致性),即数据的完整性约束没有被破坏,事务执行前后的数据状态都正常合法,其余三大特性最终目的都是保证数据的一致性

I:Isolation(隔离性),即当多个事务同时执行操作一个表的数据时,相互之间都互不干扰

D:Durability(持久性),即数据的永久性,只有数据正常操作,事务正常的提交成功,那么数据就能够永远的存储下来,不会因为断电或重启等原因导致数据的丢失

四、隔离级别的实现(读一致性解决方案)(SQL92标准)

终于搞懂Mysql事务及实现原理_第4张图片

隔离级别越高,事务并发度越低

终于搞懂Mysql事务及实现原理_第5张图片

Mysql目前的隔离方案如下

MVCC:多版本并发控制

LBCC:并发锁,加锁毫无疑问是肯定可以的,但是由于加锁的话,那么同一时间不允许其他事务进行操作,那么势必会影响效率。

MVCC实现原理(主要依赖unDo.log版本链来控制)
  1. 一个事务只能看到第一次查询之前已经提交的事务修改以及本事务的修改
  2. 一个事务不能看到当前事务第一次查询之后创建的事务,以及未提交的事务。

如何解决RC和RR的问题。生成快照(Read view)的时机

RC: 每次查询前都会先生成一个独立的Read View (导致前后俩次读取的数据不一样

RR: 只有第一次查询前生成了独立的Read View ,该事务中后续的查询都反复使用该Read View

MVCC版本比对(事务版本一次递增,只能查询到比自身版本更低版本的数据)

InnoDB锁的基本类型

锁的粒度: 表锁,行锁,MyIsam只支持表锁

锁的类型 (事务结束,锁会自动释放)

共享锁: 阻塞其他事务的修改,只允许查询,但不允许其他事务修改

排他锁:(又名写锁),同一时间只允许一个事务占有,否则其他事务将不能获取到该锁,及不能再获取该行数据,(手动加锁:select * from employee where id  1 for update)

意向锁:(表锁),该锁是由数据库自己维护的,当前若表被加了共享锁之前,会同时在该表上加上意向共享锁。意向锁的作用就是提升加锁的效率,意向锁就是相当于表中的一个标记一样,这样就不需要遍历整个表进行加锁的判断了。锁的本质就是为了解决资源竞争问题

行锁算法有如下:

记录锁(Record Lock) , 针对的是索引,锁定的也是索引  如 id=1;

间隙锁(Gap Lock),锁定索引区间,不包括Record Lock,  如:id>1and id<9

临键锁(Next-key Lock)左开右闭 ,包括Record Lock 如(1,9],

未完待续...

如有错误之处还请各位看官指点一二...  谢谢!!

你可能感兴趣的:(Mysql,mysql)