引言
最近学习了一个月了,感觉很充实,更加发现自己是多么的弱小。。。什么数据结构与算法,网络,SQL优化,SpringBoot,设计模式,高并发设计,Redis,数据库主从复制,WEB安全,WEB攻防。有一些是一整块内容,有一些是具体的内容,每一块都想学,每一块都想去了解,精通。所以又进入了什么都想学,却又觉得需要学的太多,反而无从着手的漩涡。这种感觉上周到现在一直围绕着我,让我无从下手。
我现在的心情还是蛮失落的,不过我想,慢慢来吧,反正有大把的时间挥霍~。
事务的特性
一个逻辑处理单元要成为事务,必须满足ACID(原子性,一致性,隔离性,和持久性)。
- 原子性(Atomicity) 一个事务内的操作,要么全成功,要么全不成功。
- 一致性(Consistency) 事务执行后,数据库状态与其他业务规则保持一致。
- 隔离性(Isolation) 每个事务独立运行,在并发环境中,并发的事务是互相隔离的,互不影响。
- 持久性(Durability)事务一旦提交后,数据库中的数据必须被永久的保存下来。
事务的隔离级别
数据库事务的隔离级别分为4种。
- Read_UnCommitted(未提交读)
这种隔离级别下,会产生脏读。
脏读产生的后果示例:
时间轴 | 事务A存款 | 事务B取款 |
---|---|---|
T1 | 事务A开始 | — |
T2 | ----- | 事务B开始 |
T3 | ----- | 事务B查询余额 10元 |
T4 | ----- | 事务B取出10元 |
T5 | 事务A查询余额 0元 | ----- |
T6 | ----- | 事务B撤销 余额10元 |
T7 | 事务A存入10元 | ---- |
T8 | 事务A提交 10元 | ---- |
- Read_Commited(提交读)
就是一个事务要等另一个事务提交后才能读取数据。能够解决脏读的问题,但是不能解决不可重复读的问题。不可重复读对应的是修改,即UPDATE操作。
不可重复读示例:
一个事务范围内两个相同的查询却返回了不同数据
时间轴 | 事务A查询 | 事务A取款 |
---|---|---|
T1 | ----- | 事务A开始 |
T2 | 事务A查询余额10元 | ------ |
T3 | ----- | 事务A取出10元 |
T4 | ---- | 事务A提交 |
T5 | 事务A查询余额0元 | ---- |
- RepeatAble_Read(可重复读)
重复读,就是在开始读取数据(事务开启)时,不再允许修改操作,直到事务结束,这样就保证了不可重复读。当一个事务读到了另一个事务已经提交的 insert 的数据导致多次查询结果不一致,会产生幻读,因为幻读问题对应的是插入INSERT操作,而不是UPDATE操作。
幻读的示例:
时间轴 | 事务A查询记录 | 事务B取款 |
---|---|---|
T1 | 事务A开始 | — |
T2 | ----- | 事务B开始 |
T3 | 查询交易记录 | ------ |
T4 | ----- | 事务B存入10元 |
T5 | ----- | 事务B提交 |
T6 | 查询交易记录 | ---- |
T7 | 事务A提交 | ---- |
- Serializable(顺序读)
顺序读是最严格的事务隔离级别,在该级别下,事务串行化顺序执行,可以避免脏读、不可重复读与幻读。但是这种事务隔离级别效率低下,比较耗数据库性能,一般不使用。
总结
各种级别产生的问题:
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
Read_Uncommited | 允许 | 允许 | 允许 |
Read_Commited | 不允许 | 允许 | 允许 |
Repeated_Read | 不允许 | 不允许 | 允许 |
Serializable | 不允许 | 不允许 | 不允许 |
一般数据库默认的都是RepeatAble_Read(可重复读)。
事务隔离级别越高,效率越慢,对高并发的支持越差,但是越安全。
作者:select you from me
来源:优快云
转载请联系作者获得授权并注明出处。