提示:以下是本篇文章正文内容,下面案例可供参考
一、事务的的基本概念
1. 事务存在四大特性: ACID
1.1 原子性(Atomic): 指的是事务的所有操作要不全部执行成功,要么全部执行失败,不会出现部分执行成功,部分执行失败的情况。
1.2 一致性(Consistency): 指的是事务执行之前和执行之后,数据始终处于一致的状态。
1.3 隔离性(Isolation): 事务的隔离性指的是并发执行的两个事务之间互不打扰。
1.4 持久性(Durability): 指的是事务提交之后,此事务对数据库的更改操作会被持久化到数据库中,并且不会被回滚。
2. 并发事务带来的问题:
2.1 脏写(更新丢失) : 当两个或两个以上的事务选择数据库中的同一行数据数据,并基于最初选定的值更新该数据时,因为每个事务之间都无法感知彼此的存在,所以会出现最后的更新操作覆盖之前的由其他事务完成的更新操作情况。也就是说同一行数据,一个事务对该行数据的更新操作覆盖了其他事务对于该行数据的操作。
解决方法: 开启读未提交隔离级别,能够读取到别的事务未提交的事务,但是存在以下的问题: 脏读、不可重复读、幻读
2.2 脏读: 一个事务正在对数据库中的一条记录进行修改操作,在这个事务完成并提交之前,另一个事务读取到了这条正在修改的数据,如果这个事务在提交之前进行回滚操作,另一个事务读取到的数据就是脏数据。
解决方法: 开启读已提交提交隔离级别,只能够读取到别的事务已提交的数据,但是存在不可重复读、幻读
2.3 不可重复读: 一个事务读取了某些数据,在一段时间后,这个事务再次读取之前读过的数据,此时读取的数据发生了变化,这种现象就叫做不可重复读。
解决方法: 开启可重复读隔离级别,也是MyQL默认的数据库隔离级别,同一个事务前后读取的数据前后都是一致的,在InnoDB存储引擎中通过MVCC机制实现了可重复读,MVCC机制保存了数据库中某个时间点上的数据快照,也就是说在同一个读操作的事务中,按照相同的条件查询,无论查询多少次,结果都是一样的,MVCC机制是通过两个隐藏的列来实现的,一个是创建的事务版本号,一个是更新的事务版本号,在查询操作中,只会查找小于或者等于当前事务版本号的数据行,也就是说这些要目在事务开始前就已经存在,要么就是事务本身插入或者更新的数据行
2.4 幻读 : 一个事务按照相同的查询条件重新读取之前读过的数据,此时发现其他事务插入了满足当前事务查询条件的新数据,这种现象叫做幻读。
解决方法: 开启串行化隔离级别,让所有的事务以串行的方式运行,但是会大大影响执行的效率。
注意: 不可重复读与幻读有什么区别?
- 不可重复读的重点在于更新和删除操作,而幻读的重点在于插入操作。
- 使用锁机制实现事务隔离级别时,在可重复读隔离级别中,SQL语句第一次读取到数据后,会将相应的数据加锁,使得其他事务无法修改和删除这些数据,此时可以实现可重复读,这种方法无法对新插入的数据加锁,另一个事务还可以进行插入操作,也就导致莫名其妙多了一条数据,这就是幻读。
- 幻读无法通过行级锁来避免,需要使用串行化,这会大大降低数据库的并发能力。
- 从本质上讲,不可重复读和幻读的最大区别在于如何通过锁机制来解决问题。