一看就懂的数据库锁的种类、事务的四大特性、四种隔离级别原理分析通俗易懂讲解!!!


事务:一组对数据库的读写操作,必须具有以下四种特性的操作才能叫做事务。

ACID:原子性、一致性、隔离性、持久性。

原子性:这组操作要么全部成功完成,要么就回滚到执行前的状态。

一致性:事务执行前和执行后系统的总数据是一致的,eg:银行无论怎么同行间转账,钱的总数是不变的。

隔离性:事务之间是不可见的,一个事务是感知不到其他事务的存在,就像是事务间串行化执行一样,保证了事务执行过程中短暂的不一致性对其他事务不可见。

持久性:事务完成后,事务所做出的改变会存储到数据库中,不会被回滚。

 

不考虑隔离会产生的问题:丢失更新、脏读、不可重复读(虚读、幻读)

丢失更新:当一个事务对一个数据进行修改,因为修改的操作不是原子的,再修改的过程中,另一个事务也对该数据进行修改,而如果第二个事务的修改先完成,那么第一个事务进行的修改就会把第二个事务的修改覆盖。

脏读:当一个事务执行过程中修改了某个数据,这时,另一个事务读到这个数据叫做脏读,因为如果第一个事务进行回滚的话,那么数据本身没有改变,其他事务读到的是错误的数据。

虚读:当事务读取某个数据后,另一个数据对该数据进行了修改,而第一个事务再次读取该数据就会发现两次读取结果不一致。

幻读:一个事务读取几行数据后,另一个事务插入了几行数据,则第一个事务再次读取时就会发现多了几行数据,和虚读的区别在于,虚读是针对一个数据的重复读不一致问题,幻读是对一组数据重复读的不一致。虚读的重点是修改,幻读的重点在于新增或者删除。

想要真正理解四种隔离级别需要了解下数据库的锁的种类

  共享锁:某个事务对数据加上共享锁以后,只能读取该数据,其他事务不能加排他锁,只可以加共享锁,或者直接读。

  排他锁:加了以后只能允许该事务进行读取或者修改,其他事务不能上锁,只能不加锁的读,或者等释放了锁以后再加锁。

在数据库增删改查四种操作中,insert、delete和update都是会加排它锁(Exclusive Locks)的,而select只有显式声明才会加锁:

  • select: 即最常用的查询,是不加任何锁的
  • select ... lock in share mode: 会加共享锁(Shared Locks)
  • select ... for update: 会加排它锁

四种隔离级别:都不会产生丢失更新的问题,因为产生丢失更新是事务同时对数据进行写操作,而所有的隔离级别都要求写操作必须加排他锁。

读取未提交(read-uncommitted):写加排他锁,读允许不加锁。所以最坏的情况就是,一个事务读取到另一个事务修改后但是没有提交的数据。会造成脏读、幻读、虚读。

读已提交(read-committed):如果读的时候数据被加排他锁,那就读取该数据的历史版本(MVCC),每次读取都是历史版本,这样就避免了脏读。

可重读(REPEATABLE READ):和读已提交类似只是,只有在第一次读的时候是使用MVCC查询历史版本,再继续读都是都是读到的这个版本。这样避免了虚读。

串行化(SERIALISABLE):读会加共享锁,写加排他锁。避免了所有坏的情况,但是并发度大大下降。

 

mysql默认的隔离级别是可重读。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM