ACID原则
事务的原子性(Atomicity):是指一个事务要么全部执行,要么不执行,也就是说一个事务不可能只执行了一半就停止了。比如你从取款机取钱,这个事务可以分成两个步骤:1划卡,2出钱。不可能划了卡,而钱却没出来。这两步必须同时完成,要么就不完成。
事务的一致性(Consistency):是指事务的运行并不改变数据库中数据的一致性。例如,完整性约束了a+b=10,一个事务改变了a,那么b也应该随之改变。
独立性(Isolation):事务的独立性也有称作隔离性,是指两个以上的事务不会出现交错执行的状态。因为这样可能会导致数据不一致。
持久性(Durability):事务的持久性是指事务执行成功以后,该事务对数据库所作的更改便是持久的保存在数据库之中,不会无缘无故的回滚。
行锁
- 开销大
- 加锁慢
- 会出现死锁
- 锁定粒度小
- 并发度高
- 偏向InnoDB存储引擎
- 发生锁冲突的概率最低
InnoDB支持事务,采用了行级锁
并发事务处理带来的问题
√: 可能出现 ×: 不会出现
隔离级别 脏读 不可重复读 幻读
读未提交 (Read uncommitted) √ √ √
读已提交 (Read committed) × √ √
可重复读 (Repeatable read) × × √
可串行化 (Serializable) × × ×
- 更新丢失:两个事务同时操作相同数据,后提交的事务会覆盖先提交的事务处理结果,通过乐观锁就可以解决(事务原子性问题A)
- 脏读:事务A读取到了事务B已经修改但尚未提交的数据,如果B事务回滚,A读取的数据无效,不符合一致性(事务一致性问题C)
- 不可重读(修改数据):事务A读到了事务B已经提交的修改数据,不符合隔离性(事务独立性问题I)
- 幻读(新增数据):事务A读取到了事务B提交的新增数据,不符合隔离性(事务独立性问题I)
查出当前事务隔离级别
show variables like 'tx_isolation';
MySQL中设置各事务隔离级别
set tx_isolation='read-uncommitted';
set tx_isolation='read-committed';
set tx_isolation='repeatable-read';
set tx_isolation='SERIALIZABLE';
演示隔离级别例子
脏读 事务A读取到了事务B已经修改但尚未提交的数据,如果B事务回滚,A读取的数据无效,不符合一致性.
只有在read-uncommitted读未提交情况下才会出现
set tx_isolation='READ-UNCOMMITTED'
![0a13498620a7162835f1e94b22c12af5.png](https://i-blog.csdnimg.cn/blog_migrate/f614d3d9f21c55d3793a2d9a0d77a559.jpeg)
不可重复读 修改数据时发生的
事务A读到了事务B已经提交的修改数据,不符合隔离性
read-committed read-uncommitted 情况都可能发生
set tx_isolation='read-committed'
![4d62b20429038e34a0e9f87655b33a38.png](https://i-blog.csdnimg.cn/blog_migrate/9ff5c791891e3fdf41d5ebfb01a12980.jpeg)
幻读 新增数据时发生的,数据库为提升性能采用MVCC
事务A读取到了事务B提交的新增数据,不符合隔离性
repeatable-read 情况可能发生
其它名词解释:
MVCC(多版本并发控制) Multi-Version Concurrency Control
基本原理
读取时取快照版本,更新时会取最新版本
MVCC的实现,通过保存数据在某个时间点的快照来实现的。这意味着一个事务无论运行多长时间,在同一个事务里能够看到数据一致的视图。根据事务开始的时间不同,同时也意味着在同一个时刻不同事务看到的相同表里的数据可能是不同的。
基本特征
每行数据都存在一个版本,每次数据更新时都更新该版本。 修改时Copy出当前版本随意修改,各个事务之间无干扰。 保存时比较版本号,如果成功(commit),则覆盖原记录;失败则放弃copy(rollback) InnoDB存储引擎MVCC的实现策略
在每一行数据中额外保存两个隐藏的列:当前行创建时的版本号和删除时的版本号(可能为空,其实还有一列称为回滚指针,用于事务回滚,不在本文范畴)。这里的版本号并不是实际的时间值,而是系统版本号。每开始新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询每行记录的版本号进行比较。
每个事务又有自己的版本号,这样事务内执行CRUD操作时,就通过版本号的比较来达到数据版本控制的目的。
补充:
1.MVCC手段只适用于Msyql隔离级别中的读已提交(Read committed)和可重复读(Repeatable Read).
2.Read uncimmitted由于存在脏读,即能读到未提交事务的数据行,所以不适用MVCC.
原因是MVCC的创建版本和删除版本只要在事务提交后才会产生。
3.串行化由于是会对所涉及到的表加锁,并非行锁,自然也就不存在行的版本控制问题。
4.通过以上总结,可知,MVCC主要作用于事务性的,有行锁控制的数据库模型。
间隙锁
间隙锁是一个在索引记录之间的间隙上的锁。
间隙锁的作用:保证某个间隙内的数据在锁定情况下不会发生任何变化