Mysql InnoDB的事务特征和隔离级别详解
本篇内容主要讲解"Mysql InnoDB的事务特征和隔离级别详解",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Mysql InnoDB的事务特征和隔离级别详解"吧!
Mysql-innodb-事务特征ACID
1.原子性(Atomicity):每一个事务都是一个不可分割的执行单元,该执行单元中包含一组的数据库的操作,要么都执行成功,要么执行失败全部回滚。
2.一致性(consistency):一致性体现在事务完成之后,所有的数据状态都是一致的。
3.隔离性(isolation):事务与事务执行时对数据的可见性隔离级别定义,根据不同的隔离程度,来控制读写的数据可见性,一般的指事物与事物之间是相互隔离的,互相独立的。下面会详细描述不同的隔离级别。
4.持久性(durability):事务执行完,数据的状态将会永久的保存下来。
前言
在说之前我们先了解一下脏读,不可重复读,可重复读,幻象读概念:
1.脏读:就是事务可以读到其他事务未提交的事务,但是在实际应用开发中一般的不能出现这种情况,读到不可靠的数据,导致出现异常数据,但是相信存在既有价值,脏读的好处是读取时不会对表或记录行加锁,也就是读写的时候不会阻塞等待,适合一些更新特别频繁的数据操作,并且不会场景中事务之间不会出现交叉查询。
2.不可重复读:就是事务中多次读取一条记录和最开始的读取结果不一致。如果一个事务中,读取操作不加排他锁,当多次执行一样的select 语句时,命中的数据行可能已经被其它事务修改了,这时候,就读到了其他结果,这就是不可重复读。
3.可重复读:就是事务中多次读取一条记录和最开始的读取结果一致。所以mysql-innodb默认的隔离级别就是它,也是因为事务开始的时候就会对相关的行记录加锁。
4.幻象读:是指两次执行同一条 select 语句会出现不同的结果,第二次读会增加一数据行,例如事务A更新数据,事务B在对更新后的结果进行了更新后随后同一事务中的SELECT能够看到B事务操作完成后之前不存在的记录。这时候和可重复读不一样,这里是出现新增或者删除行。
事务的隔离级别
这里讨论mysql数据库Innodb的事务隔离级别,从低到高。
1.读未提交(Read UnCommitted)简称RU:其他事务可以读到未提交的事务,该级别是最低的隔离,会出现脏读现象。
2.读已提交(Read Committed)简称RC:只能读取到已提交的事务,可以防止脏读,但是会出现不可重复读,就是同一个事务中对同一条数据查询可能会出现不同的结果。也会造成幻读现象;
3.可重复读(Repeatable Read)简称RR:是Mysql-innodb引擎默认的隔离级别。同一个事务中对同一条数据重复查询的结果和最开始查询的结果是一致的,就是可以重复读。虽然该隔离级别消除了不可重复读,但是一般的数据库引擎还是会存在幻象读,但是innoDB解决了幻读。
InnoDB使用Next-key Lock来解决"幻读"。InnoDB默认事务隔离级别为REPEATABLE READ,该隔离级别下InnoDB使用Next-key Lock来锁住相关索引记录以及记录之前的"间隙",以保证其他session中的事务不仅不能更新记录而且不能在其中插入数据,从而避免"幻读"问题。InnoDB中通过Record Lock, Gap Lock 和Next-Key Lock锁机制来实现访问控制,这里今天不做过多讨论。下一篇将详细讨论。
4.串行化(Serializable):这是最高的隔离级别,每个事务都会串行化处理,每次读都需要获得表级共享锁,读写相互都会阻塞。
隔离级别总结
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
未提交读(Read uncommitted) | 可能 | 可能 | 可能 |
已提交读(Read committed) | 不可能 | 可能 | 可能 |
未提交读(Read uncommitted) | 不可能 | 不可能 | 可能(mysql-innodb不会) |
未提交读(Read uncommitted) | 不可能 | 不可能 | 不可能 |
mysql锁知识扩展
上面讲了很多锁相关的概念,下面简单的快速带入理解一下概念,不做具体详细分析。mysql锁机制分为表级锁和行级锁,页级锁。行锁中有共享锁和排他锁之分。
1.表级锁:就是锁住整张表,开销小,加锁速度快,锁粒度大,锁的资源多,冲突概率高,容易发生死锁,并发极低。
2.行级锁:就是记录行,定位开销大,加锁速度慢,粒度小,锁住资源小,发生冲突概率小,并发相对高。
3.页面锁:介于表和行之间,给相邻一组记录加锁,并发一般。
行级锁细分-共享锁&排他锁
行级锁细分-共享锁&排他锁
1.共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。
2.排他锁又称为写锁,简称X锁,顾名思义,排他锁就是不能与其他所并存,它是独占的。如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。
备注:这里说一下排他锁:mysql InnoDB引擎默认的隔离级别在修改数据语句,update,delete,insert都会自动给涉及到的数据加上排他锁。select语句默认不会加任何锁类型,如果想加排他锁可以使用select …for update语句,共享锁可以使用select … lock in share mode。所以加过排他锁的数据行在其他事务种是不能修改数据的,也不能通过for update和lock in share mode锁的方式查询数据,但可以直接通过select …from…查询数据,因为普通查询没有任何锁机制。
乐观锁和悲观锁
有的人问乐观锁和悲观锁又是啥?这里也说一下,本人觉得乐观锁和悲观锁并不是数据库专有的,任何的锁机制都会相关概念,不要和行锁表锁和共享排他锁弄混了,悲观和乐观锁其实是一种并发控制。这里说一下数据库的乐观锁和悲观锁的实现。
1.乐观锁:使用数据库版本号或者时间戳方式实现,并发访问,当两次操作都是相同的版本号,则认为可以执行。乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。
2.悲观锁:是先获取锁,再操作的方式,如果没有获得锁,则抛出异常或者等待释放锁。数据库中也是通过行锁,表锁等机制进行访问控制的。
到此,相信大家对"Mysql InnoDB的事务特征和隔离级别详解"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!